知识大全 线程等待和释放的小麻烦(wait/notify)

Posted

篇首语:天才是百分之九十九的汗水加百分之一的灵感。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 线程等待和释放的小麻烦(wait/notify)相关的知识,希望对你有一定的参考价值。

  对于初学者来说 下面这个例子是一个非常常见的错误

  /**

  *  线程A 循环 次后等待并放弃锁 让线程B执行

  */

  class ThreadA extends Thread

  //线程同步的公共数据区

  Object oa=null;

  ThreadA(Object o)

  this oa=o;

  

  //线程A执行逻辑

  public void run()

  //线程同步区域 需要申请公共数据的锁

  synchronized(oa)

  System out println( ThreadA is running );

  for(int i= ;i< ;i++)

  System out println(    ThreadA value is +i);

  if(i== )

  try

  //当前线程等待

  Thread currentThread() wait();

   catch (InterruptedException e)

  e printStackTrace();

  

  //if(i== )

  //for(int i)

  

  

  

  /**

  *  线程B 等待线程A放弃锁 然后获得锁并执行 完成后唤醒线程A

  */

  class ThreadB extends Thread

  //线程同步的公共数据区

  Object ob=null;

  ThreadB(Object o)

  this ob=o;

  

  //线程B执行逻辑

  public void run()

  //线程同步区域 需要申请公共数据的锁

  synchronized(ob)

  System out println( ThreadB is running );

  for(int i= ;i< ;i++)

  System out println(    ThreadB value is +i);

  

  //唤醒等待的线程

  notify();

  

  

  

  //测试

  public class ThreadTest

  public static void main(String[] args)

  Object lock=new Object(); //公共数据区

  ThreadA threada=new ThreadA(lock);

  ThreadB threadb=new ThreadB(lock);

  threada start(); //线程A执行

  threadb start(); //线程B执行

  

         程序很简单 就是让线程A B交替打印 但是运行的时候会抛出两个异常

  Exception in thread Thread java lang IllegalMonitorStateException: current thread not owner

  Exception in thread Thread java lang IllegalMonitorStateException: current thread not owner

  问题就处在ThreadA中的Thread currentThread() wait(); 和ThreadB中的notify();上

  初学者理解wait()的时候都认为是将当前线程阻塞 所以Thread currentThread() wairt();视乎很有道理 但是不知道大家有没有发现 在JDK类库中wait()和notify()方法并不是Thread类的 而是Object()中的 我们仔细看看wait方法的JDK文档

  public final void wait() throws InterruptedException

  Object (Java Platform SE )<! Generated by javadoc (build beta ) on Thu Jan : : CST > <script type= text/javascript > function windowTitle() if (location href indexOf( is external=true ) == ) parent document title=&quot;Object (Java Platform SE )&quot;; </script>

  <noscript></noscript>

  在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前 导致当前线程等待 换句话说 此方法的行为就好像它仅执行 wait( ) 调用一样

  当前线程必须拥有此 对象监视器 该线程发布对此监视器的所有权并等待 直到其他线程通过调用 notify 方法 或 notifyAll 方法通知在此对象的监视器上等待的线程醒来 然后该线程将等到重新获得对监视器的所有权后才能继续执行

  对于某一个参数的版本 实现中断和虚假唤醒是可能的 而且此方法应始终在循环中使用

  synchronized (obj)

  while (<condition does not hold>)

  obj wait();

  // Perform action appropriate to condition

  

  此方法只应由作为此对象监视器的所有者的线程来调用

  抛出 IllegalMonitorStateException 如果当前线程不是此对象监视器的所有者

  InterruptedException 如果在当前线程等待通知之前或者正在等待通知时 任何线程中断了当前线程 在抛出此异常时 当前线程的中断状态 被清除

  看完JDK文档以后 很显然 只要把开始的程序中Thread currentThread() wait();改成oa wait() notify();改成 ob notify()就没有问题了

  也就是说 只能通过同步块obj来调用wait/notify方法 而不能通过想当然的线程调用这两个方法 至于为什么是这样 我有一种想法 大家可以一起讨论一下

  首先 我们都知道JVM会给每一个对象都分配唯一的一把锁 这把锁是在对象中的

  然后 当Thread 线程获得了这把锁后 应该是在对象中的锁内记录下当前占有自己的线程号 并把自己设置为已被占用 那么当Thread 需要放弃锁的时候 锁对象会吧 Thread 放入到锁的等待队列中 而这一切和Thread 是没有任何关系的 自然也轮不到Thread 对象来调用某个方法来改变另一个对象中的锁(这一点也说不通 我自己的锁凭什么让你来改)

cha138/Article/program/Java/hx/201311/26192

相关参考

知识大全 JAVA - 线程之wait(), notify()实例

JAVA-线程之wait(),notify()实例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!p

知识大全 用JAVA实现线程等待提示框

用JAVA实现线程等待提示框  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java语言从其诞生

知识大全 用JAVA实现线程等待提示框[3]

用JAVA实现线程等待提示框[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb

知识大全 用JAVA实现线程等待提示框[2]

用JAVA实现线程等待提示框[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb

知识大全 用JAVA实现线程等待提示框[1]

用JAVA实现线程等待提示框[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb

知识大全 用JAVA实现线程等待提示框[4]

用JAVA实现线程等待提示框[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb

知识大全 Java程序中的多线程

Java程序中的多线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一为什么会排队等待?  下

知识大全 麻烦帮忙找一个心理学的小故事,然后配一个相关的心理小测验

麻烦帮忙找一个心理学的小故事,然后配一个相关的心理小测验!有一位表演大师上场前,他的弟子告诉他鞋带松了。大师点头致谢,蹲下来仔细系好。等到弟子转身后,又蹲下来将鞋带解松。有个旁观者不解地问:“大师,您

知识大全 java破解ip屏蔽+多线程同步拨号

  单线程破解ip屏蔽比较容易只要拨号就行了  多线程抓取数据也比较容易但是引入多线程之后拨号就容易出现问题  多线程抓取的时候这个拨号就比较麻烦一点因为多线程拨号  会出现第一个线程拨号的时候第二个

知识大全 写一篇含有7种修辞的小短文,400字。跪谢

麻烦各位大神帮帮忙!写一篇含有7种修辞的小短文,400字。跪谢我现在就做你先彩后我达谢谢诚心第一麻烦大哥大姐帮忙写一篇英语短文.跪谢.你想做什么工作啊==我给你写个心理医生的吧,求加分iwanttob