zoukankan      html  css  js  c++  java
  • java多线程-消费者和生产者模式

    /*
    * 多线程-消费者和生产者模式
    * 在实现消费者生产者模式的时候必须要具备两个前提,一是,必须访问的是一个共享资源,二是必须要有线程锁,且锁的是同一个对象
    * */

     1 /*资源类中定义了name(名字):用来区分消费者还是生产者
     2  *         定义了flag标记:用来区分有没有货物(默认生产一个就要消费一个)
     3  *         定义了count(生产的个数统计)
     4  *     set方法:用来生产商品
     5  *     out方法:用来消费商品*/
     6 class TestSource{
     7     private String name=null;
     8     private boolean flag=false;
     9     private int count=0;
    10     /*先通过flag标记判断有没有商品,有商品则等待,没有则生产商品,唤醒所有程序,并将flag标记改变*/
    11     public synchronized void set(String name){
    12         //判断是否有产品,这里用while循环,避免在多个生产者同时生产时,会出现生产多个产品,却只消费一个
    13         while(flag){
    14             try {
    15                 wait();
    16             } catch (InterruptedException e) {
    17                 e.printStackTrace();
    18             }
    19         }
    20         //生产产品并输出
    21         this.name=name+"编号"+count++;
    22         System.out.println("生产"+name+"++");
    23         //改变标记
    24         flag=true;
    25         //唤醒所有的线程
    26         notifyAll();
    27     }
    28     public synchronized void out(){
    29         while(!flag){
    30             try {
    31                 wait();
    32             } catch (InterruptedException e) {
    33                 e.printStackTrace();
    34             }
    35         }
    36         System.out.println("消费"+name+"---");
    37         flag=false;
    38         notifyAll();
    39     }
    40 }
    41 class Product implements Runnable{
    42     private TestSource ts=null;
    43     //初始化线程里用到的资源
    44     public Product(TestSource ts){
    45         this.ts=ts;
    46     }
    47     //重写线程里run方法
    48     public void run() {
    49         while(true){
    50             ts.set("生产产品");
    51         }
    52     }
    53 }
    54 class Customer implements Runnable{
    55     private TestSource ts=null;
    56     public Customer(TestSource ts){
    57         this.ts=ts;
    58     }
    59     public void run() {
    60         while(true){
    61             ts.out();
    62         }
    63     }
    64 }
    65 public class test {
    66     public static void main(String[] args) {
    67         //初始化唯一的资源
    68         TestSource ts=new TestSource();
    69         //创建生产者和消费者两个对象,并传入两者共同操作的唯一资源
    70         Customer cu=new Customer(ts);
    71         Product pr=new Product(ts);
    72         //将对象传入线程对象
    73         Thread t1=new Thread(cu);
    74         Thread t2=new Thread(pr);
    75         Thread t3=new Thread(cu);
    76         Thread t4=new Thread(pr);
    77         //开启线程
    78         t1.start();
    79         t2.start();
    80         t3.start();
    81         t4.start();
    82     }
    83 }

    /*在java1.5版本以后,用lock和unlick代替了synchronized关键字
    * 用await()代替了wait()方法
    * 用signal()代替了notify()
    * 这里的signal可以指定唤醒莫一类的线程,而不是像notifyAll,必须全部唤醒

    这里我们对上面的代码进行一定的改写*/

     1 class TestSource{
     2     private String name=null;
     3     private boolean flag=false;
     4     private int count=0;
     5     //定义lock,用来代替synchronized关键字
     6     private Lock lock=new ReentrantLock();
     7     private Condition condition_pro=lock.newCondition();
     8     private Condition condition_con=lock.newCondition();
     9     public void set(String name){
    10         //对代码段进行上锁
    11         lock.lock();
    12         try {
    13             while(flag){
    14                 try {
    15                     //wait();
    16                     //调用生产者控制方法
    17                     condition_pro.await();
    18                 } catch (InterruptedException e) {
    19                     e.printStackTrace();
    20                 }
    21             }
    22             this.name=name+"编号"+count++;
    23             System.out.println("生产"+name+"++");
    24             flag=true;
    25             //notifyAll();
    26             //唤醒消费者线程
    27             condition_con.signal();
    28         } finally{
    29             //解锁,让其他进程进入访问
    30             lock.unlock();
    31         }
    32         
    33         
    34     }
    35     public void out(){
    36         lock.lock();
    37         try{
    38             while(!flag){
    39                 try {
    40                     //wait();
    41                     condition_con.await();
    42                 } catch (InterruptedException e) {
    43                     e.printStackTrace();
    44                 }
    45             }
    46             System.out.println("消费"+name+"---");
    47             flag=false;
    48             //notifyAll();
    49             condition_pro.signal();
    50         }finally{
    51             lock.unlock();
    52         }
    53         
    54     }
    55 }
  • 相关阅读:
    函数递归,匿名函数
    生成器
    迭代器
    有参函数(认证功能)
    闭包函数和装饰器
    文件处理
    Celery介绍
    Redis 介绍
    GIT知识点
    前后端分离-前端配置
  • 原文地址:https://www.cnblogs.com/zxxiaoxia/p/4190134.html
Copyright © 2011-2022 走看看