Java线程之1.5版新特性多生产者多消费者(四)

在Java1.5以前的版本中,因为监视器是来自于Object,为了线程的互斥访问,用的synchronized方法或者模块

  • 在synchronized中,“锁”的操作是隐式的,而且每一个锁里只能有一组wait-notify或是wait-notifyAll方法,这样的弊端在于
    等待和唤醒的缓冲线程里不仅包括了生产者也包括了消费者,这样就不能指定唤醒进程,要么唤醒了全部进程,影响了效率,要么休眠了所有进程,发生死锁

Java从1.5版本开始支持新的”锁“,体现的面向对象的特点,将锁封装起来

  • Lock实例可以通过Condition挂载多个监视器
    Condition c1 = lock.newCondition();
    Condition c2 = lock.newCondition();
    Condition中的await(),signal() ,signalAll() 来替换对应Object对象锁的方法

这样就可以实现一个锁,而指定唤醒对方进程,避免死锁,提高执行效率

java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。

java.util.concurrent.locks
接口 Lock
所有已知实现类:
ReentrantLock,ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock

  • 关于ReentrantLock
    一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

其实就是synchronized的隐形锁换成了Lock中的显示锁及显示操作

void method(){
{
    synchronized (obj)//对象锁
        {
            //code...
        }
}

改了形式

Lock lock = new ReentrantLock();//
void method()
{
    try
    {
        lock.lock();//显示获取锁
        code...throw Exception();//因为可能发生中断异常,所以把管闭锁的动作放到finally中
    }
    finally
    {
        lock.unlock();
    }

eg:

mport java.util.concurrent.locks.*;
class Resource
{
    String name;
    private int count = 1;
    String id ;
    private boolean flag = false;//初始默认没有产品

    //创建锁
    Lock lock = new ReentrantLock();
    //通过已有的锁创建两个监视,分别监视生产者和消费者
    Condition cp = lock.newCondition();//生产者监视器
    Condition cc = lock.newCondition();//消费者监视器

    public  void producer(String name)
    {
        try
        {
            lock.lock();
            while(flag)
            try{cp.await();} catch (InterruptedException ex){}//生产者等待
            this.name = name;
            id = name + count++;
            System.out.println(Thread.currentThread().getName()+"--->生产:"+id);
            flag = true;
            cc.signal();//唤醒消费者
        }
        finally 
        {
            lock.unlock();
        }
    }
    public void consumer()
    {
        try
        {
            lock.lock();
            while(!flag)
            try{cc.await();} catch (InterruptedException ex){}//消费者等待
           System.out.println(Thread.currentThread().getName()+"--------->消费"+id);
           flag = false;
           cp.signal();//唤醒生产者
        }
        finally 
        {
            lock.unlock();
        }
    }
}
class Producer implements Runnable
{
    Resource r;
    Producer(Resource r)
    {
        this.r = r;
    }
    public void run()
    {
        while(true)
        {
            r.producer("包子");
        }
    }
}
class Consumer implements Runnable
{
    Resource r;
    Consumer(Resource r)
    {
        this.r = r;
    }
    public void run()
    {
        while (true)
        {
            r.consumer();
        }
    }
}
class ThreadPC3
{
    public static void main(String[] args) 
    {
        //创建资源
        Resource r = new Resource();
        //创建线程任务
        Producer p0 = new Producer(r);
        Producer p1 = new Producer(r);
        Consumer c0 = new Consumer(r);
        Consumer c1 = new Consumer(r);
        //创建线程
        Thread tp0 = new Thread(p0);
        Thread tp1 = new Thread(p1);
        Thread tc0 = new Thread(c0);
        Thread tc1 = new Thread(c1);
        //开启线程
        tp0.start();
        tp1.start();
        tc0.start();
        tc1.start();
    }
}

这里写图片描述

这个是API中的例子:

这个不用自己实现,已经封装的

class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length) 
         notFull.await();
       items[putptr] = x; 
       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]; 
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   } 
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值