我没有看到以下代码如何产生看似违反对象锁定义的输出。当然只允许一个线程打印“获取锁定”消息,但他们都这样做了吗?
class InterruptThreadGroup {
public static void main(String[] args) {
Object lock = new Object();
MyThread mt1 = new MyThread(lock);
MyThread mt2 = new MyThread(lock);
mt1.setName("A");
mt1.start();
mt2.setName("B");
mt2.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
// Thread.currentThread().getThreadGroup().interrupt();
}
}
class MyThread extends Thread {
private Object lock;
public MyThread(Object l) {
this.lock = l;
}
public void run() {
synchronized (lock) {
System.out.println(getName() + " acquired lock");
try {
lock.wait();
} catch (InterruptedException e) {
System.out.println(getName() + " interrupted.");
}
System.out.println(getName() + " terminating.");
}
}
}
答案 0 :(得分:7)
这是因为对lock.wait()
的调用释放了锁,允许第二个线程进入同步块。摘自javadoc
线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后线程等待,直到它可以重新获得监视器的所有权并继续执行。
请注意,您的代码中存在一些问题,例如:
答案 1 :(得分:0)
您应该使用同步阻止或等待呼叫。一起使用它们是行不通的。如果你使用等待调用,则对象在同步块中释放锁。
因此请删除行lock.wait
,您的程序将按您的意愿运行。 synchronize block将自动处理所有锁定。
如果您正在使用wait,则必须使用notify。