zoukankan      html  css  js  c++  java
  • 由多线程间通信引出的等待唤醒机制

    案例: 
    生产与消费分别开一个线程,生产一个产品消费一个产品,依次执行。 

    public class ThreadDemo { 
      public static void main(String[] args) { 
        Resource r = new Resource(); 
        Producer producer = new Producer(r); 
        Consumer consumer = new Consumer(r); 
        Thread t1 = new Thread(producer); 
        Thread t2 = new Thread(consumer); 
        t1.start(); 
        t2.start(); 
      } 
    } 
    class Resource { 
      private String name; 
      private int count = 1; 
      private boolean flag = false; 
      public synchronized void set(String name) {//如果只有一个同步函数,可以使用同步函数,即在函数上加synchronzied。同步函数使用的锁是this。而当线程任务中需要多个同步时,必须用同步代码块,同步代码块使用的锁可以是任意对象。 
        if (flag) { 
          try { 
            this.wait(); 
          } catch (InterruptedException e) { 
            e.printStackTrace(); 
          } 
        } 
        this.name = name + count; 
        this.count++; 
        System.out.println(Thread.currentThread().getName() + " 生产者 " + this.name); 
        flag = true; 
        this.notify(); 
      } 
      public synchronized void out() { 
        if (!flag) { 
          try { 
            this.wait(); 
          } catch (InterruptedException e) { 
            e.printStackTrace(); 
          } 
        } 
        System.out.println(Thread.currentThread().getName() + " 消费者 " + this.name); 
        flag = false; 
        this.notify(); 
      } 
    } 
    class Producer implements Runnable { 
      private Resource r; 
      public Producer(Resource r) { 
        this.r = r; 
      } 
      public void run() { 
        while (true) { 
          r.set("面包"); 
        } 
      } 
    } 
    class Consumer implements Runnable { 
      private Resource r; 
      public Consumer(Resource r) { 
        super(); 
        this.r = r; 
      } 
      public void run() { 
        while (true) { 
          r.out(); 
        } 
      } 
    } 

    等待唤醒机制: 

    wait(); 会让线程处于等待状态,其实就是将线程临时存储到了线程池中。(wait上面必须要有锁,即synchronized同步函数,线程池是靠锁划分的。) 
    notify(); 会唤醒此线程池中任意一个等待的线程。 
    notifyAll(); 会唤醒线程池中所有的等待线程。 
    记住:上面的方法必须使用在同步中,因为必须要标识这些方法所属的锁。同一个锁上的notify只能唤醒该锁上的被wai的线程。 
    为什么这些方法定义在Object类中呢? 
    因为这些方法必须标识所属的锁,而锁可以是任意对象,任意对象可以调用的方法必然是Object类中的方法。

  • 相关阅读:
    zTree实现地市县三级级联封装类
    zTree实现地市县三级级联报错(二)
    zTree实现地市县三级级联报错(一)
    FusionCharts报错
    当分页语句遇到union all
    两表关联更新,用于update 回滚
    Invalid file system control data detected
    expect: spawn id exp4 not open
    目的可疑,但方法很值得学习的书——leo鉴书56
    下载jQuery EasyUI出现网络问题
  • 原文地址:https://www.cnblogs.com/yigechengxuyuan/p/8399667.html
Copyright © 2011-2022 走看看