首页 > 开发 > Java > 正文

java 中多线程生产者消费者问题详细介绍

2024-07-13 10:11:38
字体:
来源:转载
供稿:网友

java 中多线程生产者消费者问题

前言:

一般面试喜欢问些线程的问题,较基础的问题无非就是死锁,生产者消费者问题,线程同步等等,在前面的文章有写过死锁,这里就说下多生产多消费的问题了

import java.util.concurrent.locks.*;class BoundedBuffer {  final Lock lock = new ReentrantLock();//对象锁  final Condition notFull = lock.newCondition(); //生产者监视器  final Condition notEmpty = lock.newCondition(); //消费者监视器  //资源对象  final Object[] items = new Object[10];  //putptr生产者角标,takeptr消费者角标,count计数器(容器的实际长度)  int putptr, takeptr, count;  public void put(Object x) throws InterruptedException {    //生产者拿到锁   lock.lock();   try {     //当实际长度不满足容器的长度    while (count == items.length)       //生产者等待     notFull.await();    //把生产者产生对象加入容器    items[putptr] = x;     System.out.println(Thread.currentThread().getName()+"   put-----------"+count);    Thread.sleep(1000);    //如果容器的实际长==容器的长,生产者角标置为0    if (++putptr == items.length) putptr = 0;    ++count;    //唤醒消费者    notEmpty.signal();   } finally {     //释放锁    lock.unlock();   }  }  public Object take() throws InterruptedException {   lock.lock();   try {    while (count == 0)       //消费者等待     notEmpty.await();    Object x = items[takeptr];     System.out.println(Thread.currentThread().getName()+"   get-----------"+count);    Thread.sleep(1000);    if (++takeptr == items.length) takeptr = 0;    --count;    //唤醒生产者    notFull.signal();    return x;   } finally {     //释放锁    lock.unlock();   }  }  }class Consu implements Runnable{  BoundedBuffer bbuf;  public Consu(BoundedBuffer bbuf) {    super();    this.bbuf = bbuf;  }  @Override  public void run() {    while(true){    try {      bbuf.take() ;    } catch (InterruptedException e) {      // TODO Auto-generated catch block      e.printStackTrace();    }    }  }}class Produ implements Runnable{  BoundedBuffer bbuf;  int i=0;  public Produ(BoundedBuffer bbuf) {    super();    this.bbuf = bbuf;  }  @Override  public void run() {    while(true){      try {        bbuf.put(new String(""+i++)) ;      } catch (InterruptedException e) {        // TODO Auto-generated catch block        e.printStackTrace();      }    }  }}//主方法class Lock1{  public static void main(String[] args) {    BoundedBuffer bbuf=new BoundedBuffer();    Consu c=new Consu(bbuf);    Produ p=new Produ(bbuf);    Thread t1=new Thread(p);    Thread t2=new Thread(c);    t1.start();    t2.start();    Thread t3=new Thread(p);    Thread t4=new Thread(c);    t3.start();    t4.start();  }}

这个是jdk版本1.5以上的多线程的消费者生产者问题,其中优化的地方是把synchronized关键字进行了步骤拆分,对对象的监视器进行了拆离,synchronized同步,隐式的建立1个监听,而这种可以建立多种监听,而且唤醒也优化了,之前如果是synchronized方式,notifyAll(),在只需要唤醒消费者或者只唤醒生产者的时候,这个notifyAll()将会唤醒所有的冻结的线程,造成资源浪费,而这里只唤醒对立方的线程。代码的解释说明,全部在源码中,可以直接拷贝使用。

如有疑问请留言或者到本站社区交流讨论,希望通过本文能帮助到大家,谢谢大家对本站的支持!


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表