使用内部锁进入块
我没有看到下面的代码如何产生看起来违反对象锁定义的输出。 当然只允许一个线程打印“获取的锁定”消息,但他们都这样做?
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."); } } }
这是因为对lock.wait()
的调用释放了锁,允许第二个线程进入synchronized块。 从javadoc中提取
该线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。 然后线程等待,直到它可以重新获得监视器的所有权并继续执行。
请注意,您的代码中存在一些问题,例如:
- 你不应该在while循环之外等待
- 没有任何通知,所以你的等待可以永远持续
- 让你的任务实现Runnable并将其作为参数传递给Thread的构造函数而不是直接扩展Thread是一种更好的做法。
您应该使用同步阻止或等待呼叫。 一起使用它们是行不通的。 如果使用等待调用,则锁定由同步块中的对象释放。
所以删除行lock.wait
,你的程序将按你的意愿工作。 synchronize block将自动处理所有锁定。
如果您正在使用等待,那么必须使用通知。
这是关于这个的好主题: 为什么wait()总是在同步块中
- Java中的0.0和-0.0(IEEE 754)
- 将Java Date转换为XML Date Format(反之亦然)
- Java开发GUI的未来?
- 了解java中的最近30天,60天和90天
- 无法将.war应用程序部署到GlassFish 3.1.2
- 更改JSlider的可显示标签?
- Intellij Code Completion用于局部变量对象的所有setter / getter方法
- 将messageSource移动到applicationContext会导致默认的messageSource在dispatcher-servlet上下文中不可见
- 如何在java swing中的每个页面中用页脚打印整个JPanel