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秒发生一次
# 1 楼答案
对。这是因为您正在从线程本身内部调用
agent.getT().getState()
。线程总是将本身视为RUNNABLE
。当它被阻塞或等待时,它就不看了不,当我阅读代码时,如果它们在同一个
User
对象上工作,那么它们肯定是在相互阻塞。但是,您从未从另一个线程调用agent.getT().getState()
,因此它可以看到BLOCKED
或WAITING
状态从外部查看线程的一种方法是turning on JMX和使用jconsole。如果转到“线程”选项卡,您应该能够看到工作线程上的“总阻塞”和“总等待”计数增加
我想这就是你所期待的
# 2 楼答案
线程只锁定用户对象足够长的时间,以执行存款()或取款()操作,间隔可能为数百毫秒。除非deposit()或Draw()依赖于高延迟的外部资源,否则它们可能在几分之一微秒的时间内执行,这就足够了,比如说,数千行代码。因此,在线程锁定用户对象的状态下捕获系统的几率可能小于1/100000。此外,要阻止另一个线程,它也需要尝试执行存款()或取款()操作。考虑到你可能的参数,发生这种碰撞的几率不到百万分之一,这很可能解释了为什么你从未见过它