WEB开发网
开发学院软件开发Java Java 多线程同步问题的探究(四、协作,互斥下的协... 阅读

Java 多线程同步问题的探究(四、协作,互斥下的协作——Java多线程协作(wait、notify、notifyAll))

 2010-05-14 00:00:00 来源:WEB开发网   
核心提示: 这段代码启动了三个简单的wait线程,当他们处于等待状态以后,Java 多线程同步问题的探究(四、协作,互斥下的协作——Java多线程协作(wait、notify、notifyAll))(2),试图由一个notify线程来唤醒,运行这段程序,在上面的例程中,我们用第三种方法比较合适,你会发现,满

这段代码启动了三个简单的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.             } 

上一页  1 2 3 4 5 6 7  下一页

Tags:Java 线程 同步

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接