有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java同步线程不相互阻塞

我不想在黑板上再添一个同样的问题,但我读了大约15个解决方案,没有人有完全相同的问题。以下是我正在查看的代码:

private AgentModel agent;
private UserModel user;
private int type;

public AgentThread(AgentModel agent, UserModel user, int type) {
    this.agent = agent;
    this.user = user;
    this.type = type;
}

public void start() throws InterruptedException {
    agent.setT(new Thread(this, agent.getID()));
    agent.getT().start();
}

再往下一点:

public void run() {
    while (!agent.getT().isInterrupted()) {
        agent.nextOP();

        try {
            if (agent.getOPS() > 0) {
                agent.getT().sleep((long) (1000 / agent.getOPS()));
            } else {
                agent.getT().sleep(1000);
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            agent.getT().interrupt();
        }
        synchronized (user) {
            agent.setState(agent.getT().getState().toString());
            // System.out.println("Operations Completed: " +
            // (1+agent.getOPCompleted()) );
            if (type == 3) {
                user.deposit(agent.getAmount(), Integer.valueOf(agent.getID()));
            }
            if (type == 4) {
                user.withdraw(agent.getAmount(), Integer.valueOf(agent.getID()));
            }
        }
    }
}

代理对象包含在AgentThread start方法中启动的线程。AgentThread对象接收代理和用户及其各自类的实例

我的问题如下:我将锁设置为UserModel类“user”的实例。线程应该根据其代理类型进行存款或取款

当我执行agent.getT().getState()时,无论我创建了多少个AgentThread实例,它总是返回RUNNABLE。每个AgentThread都被赋予一个新的代理和一个新的线程,但具有相同的用户对象。似乎线程从未相互阻塞

我知道它们正在影响同一个用户实例,因为我可以输出侦听器检测到的更改,它反映了所有正在运行的线程及其与该用户实例的交互

每次线程启动时,它都会进入一个“无限”循环,其中用户实例有存款或取款。这些动作每x秒发生一次


共 (2) 个答案

  1. # 1 楼答案

    When I execute agent.getT().getState(), it always returns RUNNABLE no matter how many instances of AgentThread I have created.

    对。这是因为您正在从线程本身内部调用agent.getT().getState()。线程总是将本身视为RUNNABLE。当它被阻塞或等待时,它就不看了

    It seems as though the threads are never blocking each other.

    不,当我阅读代码时,如果它们在同一个User对象上工作,那么它们肯定是在相互阻塞。但是,您从未从另一个线程调用agent.getT().getState(),因此它可以看到BLOCKEDWAITING状态

    从外部查看线程的一种方法是turning on JMX和使用jconsole。如果转到“线程”选项卡,您应该能够看到工作线程上的“总阻塞”和“总等待”计数增加

    Every time a thread is started it enters an "infinite" loop where the user instance has a deposit or a withdrawal. These actions happen every x seconds.

    我想这就是你所期待的

  2. # 2 楼答案

    线程只锁定用户对象足够长的时间,以执行存款()或取款()操作,间隔可能为数百毫秒。除非deposit()或Draw()依赖于高延迟的外部资源,否则它们可能在几分之一微秒的时间内执行,这就足够了,比如说,数千行代码。因此,在线程锁定用户对象的状态下捕获系统的几率可能小于1/100000。此外,要阻止另一个线程,它也需要尝试执行存款()或取款()操作。考虑到你可能的参数,发生这种碰撞的几率不到百万分之一,这很可能解释了为什么你从未见过它