黑马程序员技术交流社区

标题: 多线程——等待唤醒机制 [打印本页]

作者: 水蛭31    时间: 2015-6-19 11:01
标题: 多线程——等待唤醒机制
多线程——等待唤醒机制接着线程之间的通信, 这里有个问题, 同步了, 但是运行的话, 会执行一大片, 但是一般都是存一个,输出一个,
为什么会执行一大片?
一个线程可能一直拥有CPU的执行权;
如何解决?(参考代码)
这里可以用一个标记来标识(flag),当存一个完了之后, 就改变这个标识,当下次再执行时, 就不会再存了,
此时可以将这个线程1给冻结(sleep(时间(毫秒)),wait()),如果用sleep(),时间不确定, 所以就用wait(),当执行完了之后,
标识发生改变,再次执行时, 就处于冻结状态了,失去执行资格。
那什么时候恢复执行资格呢?
当另一个线程2进来将这个存的值,取走了, 就恢复执行资格,如何恢复?
当取走后, 标识再次发生改变,然后用notify(),唤醒线程1,此时如果这个线程2再次执行时, 由于没有了值, 那么就将线程2冻结,wait()。
这个过程就是线程间的等待唤醒机制。
代码如下:
  1. class Res //共享资源的类
  2. {
  3.         String name;
  4.         String sex;
  5.         boolean flag=false;
  6. }
  7. /*
  8. 等待的线程在哪里呢?
  9. 线程运行的时候, 内存中会建立一个叫做线程池的,等待线程都存放在线程池中,
  10. 当notify的时候, 都是唤醒的是线程池中的线程,当线程池中有许多的线程都在等待,
  11. 通常是唤醒第一被等待的线程, 按照顺序来叫醒

  12. */
  13. class Input implements Runnable//需要用到一个资源,
  14. {
  15.         private Res r;
  16.         Input(Res r){//传递过来一个资源类的对象
  17.                 this.r=r;
  18.         }
  19.         public void run(){
  20.                 int x=0;
  21.                 while(true)
  22.                 {
  23.                         synchronized(r)//这里需要同步,
  24.                         {       
  25.                                 if(r.flag){
  26.                                         try{r.wait();}catch(Exception e){}//当为真时, 就等待, 不能再传值了,因为已经有值
  27.                                 }
  28.                                 if(x==0){
  29.                                 r.name="mike";
  30.                                 r.sex="man";
  31.                         }
  32.                                 else{
  33.                                         r.name="小王";
  34.                                         r.sex="女女女女女女";
  35.                                 }
  36.                                 x=(x+1)%2;
  37.                                 r.flag=true;
  38.                                 r.notify();//在线程池中叫醒Output线程
  39.                         }
  40.                 }
  41.         }
  42. }
  43. class Output implements Runnable
  44. {
  45.         private Res r;
  46.         Output(Res r){
  47.                 this.r=r;
  48.         }
  49.         public void run(){
  50.                 while(true)
  51.                 {
  52.                         synchronized(r){//这里也需要同步,并且锁需要是同一个锁。
  53.                                 if(!r.flag){
  54.                                         try{r.wait();}catch(Exception e){}
  55.                                 }
  56. //Wait(), notify(), notifyAll(), 全部用在同步中,因为需要锁必须标识wait()线程所处的锁
  57.                                 System.out.println(r.name+"....."+r.sex);
  58.                                 r.flag=false;
  59.                                 r.notify();
  60.                         }
  61.                 }
  62.         }
  63. }
  64. class ThreadInputOutput
  65. {
  66.         public static void main(String[] args)
  67.         {
  68.                 Res r=new Res();
  69.                 Input in=new Input(r);
  70.                 Output out=new Output(r);
  71.                 Thread t1=new Thread(in);
  72.                 Thread t2=new Thread(out);
  73.                 t1.start();
  74.                 t2.start();
  75.         }
  76. }
复制代码








欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2