当前位置: 移动技术网 > IT编程>开发语言>Java > java 中多线程生产者消费者问题详细介绍

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

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()将会唤醒所有的冻结的线程,造成资源浪费,而这里只唤醒对立方的线程。代码的解释说明,全部在源码中,可以直接拷贝使用。

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网