Java 多线程同步问题的探究(四、协作,互斥下的协作——Java多线程协作(wait、notify、notifyAll))
2010-05-14 00:00:00 来源:WEB开发网这段代码启动了三个简单的wait线程,当他们处于等待状态以后,试图由一个notify线程来唤醒。
运行这段程序,你会发现,满屏的java.lang.IllegalMonitorStateException,根本不是你想要的结果。
请注意以下几个事实:
1. 任何一个时刻,对象的控制权(monitor)只能被一个线程拥有。
2. 无论是执行对象的wait、notify还是notifyAll方法,必须保证当前运行的线程取得了该对象的控制权(monitor)。
3. 如果在没有控制权的线程里执行对象的以上三种方法,就会报java.lang.IllegalMonitorStateException异常。
4. JVM基于多线程,默认情况下不能保证运行时线程的时序性。
也就是说,当线程在调用某个对象的wait或者notify方法的时候,要先取得该对象的控制权,换句话说,就是进入这个对象的监视器。
通过前面对同步的讨论,我们知道,要让一个线程进入某个对象的监视器,通常有三种方法:
1: 执行对象的某个同步实例方法
2: 执行对象对应的同步静态方法
3: 执行对该对象加同步锁的同步块
显然,在上面的例程中,我们用第三种方法比较合适。
于是我们将上面的wait和notify方法调用包在同步块中。
1. synchronized (flag) {
2. flag = "false";
3. flag.notify();
4. }
1. synchronized (flag) {
2. while (flag!="false") {
3. System.out.println(getName() + " begin waiting!");
4. long waitTime = System.currentTimeMillis();
5. try {
6. flag.wait();
7. } catch (InterruptedException e) {
8. e.printStackTrace();
9. }
10. waitTime = System.currentTimeMillis() - waitTime;
11. System.out.println("wait time :"+waitTime);
12. }
13. System.out.println(getName() + " end waiting!");
14. }
赞助商链接