Java学习-Lock机制和Synchronized分析

来源:互联网 发布:大数据的发展图片 编辑:程序博客网 时间:2024/06/06 00:12

分析:
Condition的强大之处在于它可以为多个线程间建立不同的Condition, 使用synchronized/wait()只有一个阻塞队列,notifyAll会唤起所有阻塞队列下的线程,而使用lock/condition,可以实现多个阻塞队列,signalAll只会唤起某个阻塞队列下的阻塞线程。

- 使用synchronized/wait()实现生产者消费者模式如下:

 //模拟生产和消费的对象    class Buffer {        private int maxSize;        private List<Date> storage;        Buffer(int size){            maxSize=size;            storage=new LinkedList<>();        }        //生产方法        public synchronized void put()  {            try {                while (storage.size() ==maxSize ){//如果队列满了                    System.out.print(Thread.currentThread().getName()+": wait \n");;                    wait();//阻塞线程                }                storage.add(new Date());                System.out.print(Thread.currentThread().getName()+": put:"+storage.size()+ "\n");                Thread.sleep(1000);                notifyAll();//唤起线程            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }               }        //消费方法        public synchronized void take() {            try {                 while (storage.size() ==0 ){//如果队列满了                    System.out.print(Thread.currentThread().getName()+": wait \n");;                    wait();//阻塞线程                }                Date d=((LinkedList<Date>)storage).poll();                System.out.print(Thread.currentThread().getName()+": take:"+storage.size()+ "\n");                Thread.sleep(1000);                notifyAll();//唤起线程            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }               } }//生产者class Producer implements Runnable{    private Buffer buffer;    Producer(Buffer b){        buffer=b;    }    @Override    public void run() {        while(true){            buffer.put();        }    }   }//消费者class Consumer implements Runnable{    private Buffer buffer;    Consumer(Buffer b){        buffer=b;    }    @Override    public void run() {        while(true){            buffer.take();        }    }   }//public class Main{    public static void main(String[] arg){        Buffer buffer=new Buffer(10);        Producer producer=new Producer(buffer);        Consumer consumer=new Consumer(buffer);        //创建线程执行生产和消费        for(int i=0;i<3;i++){            new Thread(producer,"producer-"+i).start();        }        for(int i=0;i<3;i++){            new Thread(consumer,"consumer-"+i).start();        }    }}

- 使用lock/condition实现生产者消费者模式如下:

import java.util.Date;import java.util.LinkedList;import java.util.List;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class Buffer {    private  final Lock lock;    private  final Condition notFull;    private  final Condition notEmpty;    private int maxSize;    private List<Date> storage;    Buffer(int size){        //使用锁lock,并且创建两个condition,相当于两个阻塞队列        lock=new ReentrantLock();        notFull=lock.newCondition();        notEmpty=lock.newCondition();        maxSize=size;        storage=new LinkedList<>();    }    public void put()  {        lock.lock();        try {               while (storage.size() ==maxSize ){//如果队列满了                System.out.print(Thread.currentThread().getName()+": wait \n");;                notFull.await();//阻塞生产线程            }            storage.add(new Date());            System.out.print(Thread.currentThread().getName()+": put:"+storage.size()+ "\n");            Thread.sleep(1000);                     notEmpty.signalAll();//唤醒消费线程        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally{               lock.unlock();        }    }    public  void take() {               lock.lock();        try {              while (storage.size() ==0 ){//如果队列为空                System.out.print(Thread.currentThread().getName()+": wait \n");;                notEmpty.await();//阻塞消费线程            }            Date d=((LinkedList<Date>)storage).poll();            System.out.print(Thread.currentThread().getName()+": take:"+storage.size()+ "\n");            Thread.sleep(1000);                     notFull.signalAll();//唤醒生产线程        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally{            lock.unlock();        }    } }class Producer implements Runnable{    private Buffer buffer;    Producer(Buffer b){        buffer=b;    }    @Override    public void run() {        while(true){            buffer.put();        }    }   }class Consumer implements Runnable{    private Buffer buffer;    Consumer(Buffer b){        buffer=b;    }    @Override    public void run() {        while(true){            buffer.take();        }    }   }public class Main{    public static void main(String[] arg){        Buffer buffer=new Buffer(10);        Producer producer=new Producer(buffer);        Consumer consumer=new Consumer(buffer);        for(int i=0;i<3;i++){            new Thread(producer,"producer-"+i).start();        }        for(int i=0;i<3;i++){            new Thread(consumer,"consumer-"+i).start();        }    }}
  • 当生产者执行put方法时,调用notEmpty.signalAll()只会唤醒notEmpty.await()下的消费者线程。
    - 当消费者执行塔克方法时,调用notFull.signalAll()只会唤醒notFull.await()下的消费者线程。
阅读全文
0 0
原创粉丝点击