zoukankan      html  css  js  c++  java
  • Java学习之线程通信(多线程(synchronized))--生产者消费者

    分析线程经典案例生产者消费者

     1 /**
     2 共享数据
     3 */
     4 class Resource
     5 {
     6     private String name;
     7     private int count=1;
     8     private boolean flag=false;
     9     
    10     public synchronized void set(String name)
    11     {    
    12         if(flag)
    13             try{this.wait();}catch(InterruptedException e){}
    14         this.name=name+count;
    15         count++;
    16         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
    17         flag = true;
    18         notify();
    19     }
    20     
    21     public synchronized void out() 
    22     {
    23         if(!flag)
    24             try{this.wait();}catch(InterruptedException e){}
    25         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
    26         flag = false;
    27         notify();
    28     }
    29 }
    30 
    31 //定义线程任务(生产者线程)
    32 class Producer implements Runnable
    33 {
    34     private Resource r;
    35     
    36     Producer(Resource r)
    37     {
    38         this.r=r;
    39     }
    40     public void run()
    41     {
    42         while(true)
    43         {
    44             r.set("商品");
    45         }
    46     }
    47 }
    48 //定义线程任务(消费者线程)
    49 class Consumer implements Runnable
    50 {
    51     private Resource r;
    52     
    53     Consumer(Resource r)
    54     {
    55         this.r=r;
    56     }
    57     
    58     public void run()
    59     {
    60         while(true)
    61         {
    62             r.out();
    63         }
    64     }
    65 }
    66 
    67 class ProducerConsumerDemo
    68 {
    69     public static void main(String[] args)
    70     {
    71         //实例化共享资源
    72         Resource r = new Resource();
    73         //实例化线程任务,指定共享资源
    74         Producer p=new Producer(r);
    75         Consumer c=new Consumer(r);
    76         //实例化线程,指定线程任务
    77         Thread t0=new Thread(p);
    78         Thread t1=new Thread(p);
    79         Thread t2=new Thread(c);
    80         Thread t3=new Thread(c);
    81         //开启线程,执行线程任务中的run方法
    82         t0.start();
    83         t1.start();
    84         t2.start();
    85         t3.start();
    86     }
    87 }

    运行结果:

    结果分析:

    那么怎么再判断flag呢?while

    代码如下:

     1 class Resource
     2 {
     3     private String name;
     4     private int count=1;
     5     private boolean flag=false;
     6     
     7     public synchronized void set(String name) // 有两个线程t0 t1
     8     {    
     9         while(flag)
    10             try{this.wait();}catch(InterruptedException e){}
    11         this.name=name+count;
    12         count++;
    13         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
    14         flag = true;
    15         notify();
    16     }
    17     
    18     public synchronized void out() // 有两个线程t2 t3
    19     {
    20         while(!flag)
    21             try{this.wait();}catch(InterruptedException e){}
    22         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
    23         flag = false;
    24         notify();
    25     }
    26 }

    结果出现死锁:

    结果分析:

    通过分析,那能不能每次唤醒只唤醒对方线程(如生产者线程只唤醒消费者线程,消费者线程只唤醒生产者线程),查看Object对象方法中没有,但是有一个notifyAll()方法,实在不行就把所有阻塞线程(相同同步锁的线程)都唤醒。

     1 class Resource
     2 {
     3     private String name;
     4     private int count=1;
     5     private boolean flag=false;
     6     
     7     public synchronized void set(String name) // 有两个线程t0 t1
     8     {    
     9         while(flag)
    10             try{this.wait();}catch(InterruptedException e){}
    11         this.name=name+count;
    12         count++;
    13         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
    14         flag = true;
    15         notifyAll();
    16     }
    17     
    18     public synchronized void out() // 有两个线程t2 t3
    19     {
    20         while(!flag)
    21             try{this.wait();}catch(InterruptedException e){}
    22         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
    23         flag = false;
    24         notifyAll();
    25     }
    26 }

    结果:

    这样就可以了。

    总结:

    if判断只能判断一次,如果执行等待方法,下次唤醒的线程获取执行权后(唤醒后的线程会从上次等待位置,向下执行)就不能再判断

    while判断解决唤醒的线程获取执行权后无法判断

    notify:只能唤醒任意一个线程,有可能会唤醒本方线程,while+notify会导致死锁

    notifyAll:解决了死锁问题

  • 相关阅读:
    366. Find Leaves of Binary Tree输出层数相同的叶子节点
    716. Max Stack实现一个最大stack
    515. Find Largest Value in Each Tree Row查找一行中的最大值
    364. Nested List Weight Sum II 大小反向的括号加权求和
    156. Binary Tree Upside Down反转二叉树
    698. Partition to K Equal Sum Subsets 数组分成和相同的k组
    244. Shortest Word Distance II 实现数组中的最短距离单词
    187. Repeated DNA Sequences重复的DNA子串序列
    java之hibernate之基于主键的双向一对一关联映射
    java之hibernate之基于主键的单向一对一关联映射
  • 原文地址:https://www.cnblogs.com/WarBlog/p/12082961.html
Copyright © 2011-2022 走看看