同步线程互不阻塞

时间:2016-04-29 17:16:13

标签: java multithreading synchronized

我不是试图用另一个同样的问题填补董事会,但我读了大约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都被赋予一个新的代理和一个新的线程但是相同的User对象。似乎线程永远不会相互阻塞。

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

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

2 个答案:

答案 0 :(得分:0)

线程只锁定User对象足够的时间,以大约几百毫秒的间隔执行deposit()或withdraw()操作。除非deposit()或withdraw()依赖于高延迟外部资源,否则它们可能只需几微秒就可以执行,这对于数千行代码就足够了。因此,在线程锁定了User对象的状态下捕获系统的可能性可能小于100,000。另外,对于另一个要阻塞的线程,它也需要尝试执行deposit()或withdraw()操作。鉴于您可能的参数,这种碰撞的可能性不到百万分之一,这可能解释了为什么您从未见过它。

答案 1 :(得分:0)

  

当我执行agent.getT()。getState()时,无论我创建了多少个AgentThread实例,它总是返回RUNNABLE。

右。这是因为您从线程内部调用agent.getT().getState()。该线程将始终将本身视为RUNNABLE。当它被阻止或等待时,它不会看。

  

似乎线程永远不会互相阻塞。

不,当我阅读代码时,如果他们正在处理相同的User对象,他们肯定会互相阻塞。但是,您永远不会从其他线程调用agent.getT().getState(),因此它可以看到BLOCKEDWAITING个州。

从外部查看线程的一种方法是turning on JMX并使用jconsole。如果你进入线程标签,你应该能够看到" Total blocked"和#34;总等待"计数会增加你的工作线程。

  

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

我认为这是你所期待的。