zoukankan      html  css  js  c++  java
  • Java度线程——生产消费问题


    /*
    JDK1.4版本:生产者,消费者。
    多生产者,多消费者的问题。
    if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
    while判断标记,解决了线程获取执行权后,是否要运行!

    notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。
    notifyAll解决了本方线程一定会唤醒对方线程的问题。

    该方法虽然可行,但是效率并非最好,JDK1.4版本已经无法解决效率问题,需要JDK1.5版本才能解决
    */

     1 class Resource
     2 {
     3     private String name;
     4     private int count = 1;
     5     private boolean flag = false;
     6     public synchronized void set(String name)//  
     7     {
     8         while(flag)
     9             try{this.wait();}catch(InterruptedException e){}//   t1    t0
    10         
    11         this.name = name + count;//烤鸭1  烤鸭2  烤鸭3
    12         count++;//2 3 4
    13         System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3
    14         flag = true;
    15         notifyAll();
    16     }
    17 
    18     public synchronized void out()//  t3
    19     {
    20         while(!flag)
    21             try{this.wait();}catch(InterruptedException e){}    //t2  t3
    22         System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name);//消费烤鸭1
    23         flag = false;
    24         notifyAll();
    25     }
    26 }
    27 
    28 class Producer implements Runnable
    29 {
    30     private Resource r;
    31     Producer(Resource r)
    32     {
    33         this.r = r;
    34     }
    35     public void run()
    36     {
    37         while(true)
    38         {
    39             r.set("烤鸭");
    40         }
    41     }
    42 }
    43 
    44 class Consumer implements Runnable
    45 {
    46     private Resource r;
    47     Consumer(Resource r)
    48     {
    49         this.r = r;
    50     }
    51     public void run()
    52     {
    53         while(true)
    54         {
    55             r.out();
    56         }
    57     }
    58 }
    59 
    60 
    61 
    62 public class  ProducerConsumerDemo
    63 {
    64     public static void main(String[] args)
    65     {
    66         Resource r = new Resource();
    67         Producer pro = new Producer(r);
    68         Consumer con = new Consumer(r);
    69 
    70         Thread t0 = new Thread(pro);
    71         Thread t1 = new Thread(pro);
    72         Thread t2 = new Thread(con);
    73         Thread t3 = new Thread(con);
    74         t0.start();
    75         t1.start();
    76         t2.start();
    77         t3.start();
    78 
    79     }
    80 }
    JDK1.4


    --------------------------------------------------------------------------------------------------------------------------
    /*
    jdk1.5以后将同步和锁封装成了对象。
    并将操作锁的隐式方式定义到了该对象中,
    将隐式动作变成了显示动作。

    Lock接口: 出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成现实锁操作。
    同时更为灵活。可以一个锁上加上多组监视器。
    lock():获取锁。
    unlock():释放锁,通常需要定义finally代码块中。


    Condition接口:出现替代了Object中的wait notify notifyAll方法。
                将这些监视器方法单独进行了封装,变成Condition监视器对象。
                可以任意锁进行组合。
    await();
    signal();
    signalAll();

    该版本能够提高效率,因为我们不必唤醒所有对象,做多余的判断;

    当然在这我们可以指定对象唤醒,在生产者生产完毕后,只需要唤醒消费者中的对象即可;反义,在消费者消费完毕后,我们只需指定唤醒生产者即可。

    故我们的效率有所提升,因为不需要做多余的判断。
    */

      1 import java.util.concurrent.locks.*;
      2 
      3 class Resource
      4 {
      5     private String name;
      6     private int count = 1;
      7     private boolean flag = false;
      8 
      9 //    创建一个锁对象。
     10     Lock lock = new ReentrantLock();
     11 
     12     //通过已有的锁获取该锁上的监视器对象。
     13 //    Condition con = lock.newCondition();
     14 
     15     //通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。
     16     Condition producer_con = lock.newCondition();
     17     Condition consumer_con = lock.newCondition();
     18 
     19     
     20     public  void set(String name)//  t0 t1
     21     {
     22         lock.lock();
     23         try
     24         {
     25             while(flag)
     26 //            try{lock.wait();}catch(InterruptedException e){}//   t1    t0
     27             try{producer_con.await();}catch(InterruptedException e){}//   t1    t0
     28         
     29             this.name = name + count;//烤鸭1  烤鸭2  烤鸭3
     30             count++;//2 3 4
     31             System.out.println(Thread.currentThread().getName()+"...生产者5.0..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3
     32             flag = true;
     33 //            notifyAll();
     34 //            con.signalAll();
     35             consumer_con.signal();
     36         }
     37         finally
     38         {
     39             lock.unlock();
     40         }
     41         
     42     }
     43 
     44     public  void out()// t2 t3
     45     {
     46         lock.lock();
     47         try
     48         {
     49             while(!flag)
     50 //            try{this.wait();}catch(InterruptedException e){}    //t2  t3
     51             try{cousumer_con.await();}catch(InterruptedException e){}    //t2  t3
     52             System.out.println(Thread.currentThread().getName()+"...消费者.5.0......."+this.name);//消费烤鸭1
     53             flag = false;
     54 //            notifyAll();
     55 //            con.signalAll();
     56             producer_con.signal();
     57         }
     58         finally
     59         {
     60             lock.unlock();
     61         }
     62         
     63     }
     64 }
     65 
     66 class Producer implements Runnable
     67 {
     68     private Resource r;
     69     Producer(Resource r)
     70     {
     71         this.r = r;
     72     }
     73     public void run()
     74     {
     75         while(true)
     76         {
     77             r.set("烤鸭");
     78         }
     79     }
     80 }
     81 
     82 class Consumer implements Runnable
     83 {
     84     private Resource r;
     85     Consumer(Resource r)
     86     {
     87         this.r = r;
     88     }
     89     public void run()
     90     {
     91         while(true)
     92         {
     93             r.out();
     94         }
     95     }
     96 }
     97 
     98 
     99 
    100 class  ProducerConsumerDemo2
    101 {
    102     public static void main(String[] args)
    103     {
    104         Resource r = new Resource();
    105         Producer pro = new Producer(r);
    106         Consumer con = new Consumer(r);
    107 
    108         Thread t0 = new Thread(pro);
    109         Thread t1 = new Thread(pro);
    110         Thread t2 = new Thread(con);
    111         Thread t3 = new Thread(con);
    112         t0.start();
    113         t1.start();
    114         t2.start();
    115         t3.start();
    116 
    117     }
    118 }
    JDK1.5
  • 相关阅读:
    .Net EF中DbContext动态生成DbSet
    .net core 3.0 中间件或过滤器中读取post请求body方法
    Asp.Net Core 5 WebAPI发布后的Swagger不显示问题
    .net Core 使用Swagger 让某些接口不显示在文档
    C# Request.InputStream 读取输入流为空的原因处理
    ASP.NET 中的缓存
    缓存依赖(文件、数据库)
    NLTK基本使用
    NLTK基本使用
    NLTK的基本使用
  • 原文地址:https://www.cnblogs.com/HOsystem/p/10886669.html
Copyright © 2011-2022 走看看