我不是试图用另一个同样的问题填补董事会,但我读了大约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秒发生一次。
答案 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()
,因此它可以看到BLOCKED
或WAITING
个州。
从外部查看线程的一种方法是turning on JMX并使用jconsole。如果你进入线程标签,你应该能够看到" Total blocked"和#34;总等待"计数会增加你的工作线程。
每次线程启动时,它都会进入"无限"用户实例有存款或取款的循环。这些动作每隔x秒发生一次。
我认为这是你所期待的。