java多线程---等待/唤醒以及生产者消费者经典同步Lock的实现

来源:互联网 发布:软件可靠性英文 编辑:程序博客网 时间:2024/06/04 19:27

在jdk1.5并发包中引入的Lock,其主要实现重入锁,和读写锁,并且相对于synchronized原生的将锁的获取和释放显示化,并且可以提供了非阻塞的获取锁,并结合condition实现多路分之,将条件更加细化,并且比synchronized效率更高,但是在jdk1.6,对synchronized做出了很多优化,所以性能不一定比lock差,下面给出使用lock来实现等待/唤醒和之前的生产者消费者同步问题的代码:

package com.zcj.thread03;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class LockTest {    private Lock lock = new ReentrantLock();    private Condition condition = lock.newCondition();        public void waitTest(){    lock.lock();    try{    System.out.println("我开始等待,等待被唤醒!");    condition.await();    System.out.println("我已经被唤醒!");    }catch(InterruptedException e){    e.printStackTrace();    }finally{    lock.unlock();    }    }        public void signalTest(){    lock.lock();    System.out.println("我唤醒等待线程");    condition.signal();    lock.unlock();    }        public static void main(String[] args) {LockTest lockTest = new LockTest();ThreadA threadA = new ThreadA(lockTest);ThreadB threadB = new ThreadB(lockTest);threadA.start();try {Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}threadB.start();}}class ThreadA extends Thread{private LockTest lockTest;public ThreadA(LockTest lockTest){this.lockTest = lockTest;}@Overridepublic void run(){lockTest.waitTest();}}class ThreadB extends Thread{private LockTest lockTest;public ThreadB(LockTest lockTest){this.lockTest = lockTest;}@Overridepublic void run(){lockTest.signalTest();}}
单个消费者和单个生产者的同步代码如下:

package com.zcj.thread03;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class LockTest {private int count=1;    private Lock lock = new ReentrantLock();    private Condition condition = lock.newCondition();    private Condition condition2 = lock.newCondition();        public void produce(){    lock.lock();    try{    if(count==1){    condition.await();    }    count=1;    System.out.println("生产者生产商品!");    condition2.signal();    }catch(InterruptedException e){    e.printStackTrace();    }finally{    lock.unlock();    }    }        public void consume(){    lock.lock();    try{    if(count==0){    condition2.await();    }    count=0;    System.out.println("消费者消费商品!");    condition.signal();    }catch(InterruptedException e){    e.printStackTrace();    }finally{    lock.unlock();    }        }        public static void main(String[] args) {LockTest lockTest = new LockTest();ThreadA threadA = new ThreadA(lockTest);ThreadB threadB = new ThreadB(lockTest);threadA.start();threadB.start();}}class ThreadA extends Thread{private LockTest lockTest;public ThreadA(LockTest lockTest){this.lockTest = lockTest;}@Overridepublic void run(){while(true){lockTest.produce();}}}class ThreadB extends Thread{private LockTest lockTest;public ThreadB(LockTest lockTest){this.lockTest = lockTest;}@Overridepublic void run(){while(true){lockTest.consume();}}}
从代码中可以看出使用lock我们可以指定唤醒什么条件下的线程

接下来编写多个消费者和多个生产者,只需要把if改为while和signal改为signalAll即可,代码如下:

package com.zcj.thread03;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class LockTest {private int count=1;    private Lock lock = new ReentrantLock();    private Condition condition = lock.newCondition();    private Condition condition2 = lock.newCondition();        public void produce(){    lock.lock();    try{    while(count==1){    condition.await();    }    count=1;    System.out.println(Thread.currentThread().getName()+"生产者生产商品!");    condition2.signalAll();    }catch(InterruptedException e){    e.printStackTrace();    }finally{    lock.unlock();    }    }        public void consume(){    lock.lock();    try{    while(count==0){    condition2.await();    }    count=0;    System.out.println(Thread.currentThread().getName()+"消费者消费商品!");    condition.signalAll();    }catch(InterruptedException e){    e.printStackTrace();    }finally{    lock.unlock();    }        }        public static void main(String[] args) {LockTest lockTest = new LockTest();ThreadA threadA = new ThreadA(lockTest);ThreadA threadA1 = new ThreadA(lockTest);ThreadB threadB = new ThreadB(lockTest);ThreadB threadB1 = new ThreadB(lockTest);threadA.start();threadA1.start();threadB.start();threadB1.start();}}class ThreadA extends Thread{private LockTest lockTest;public ThreadA(LockTest lockTest){this.lockTest = lockTest;}@Overridepublic void run(){while(true){lockTest.produce();}}}class ThreadB extends Thread{private LockTest lockTest;public ThreadB(LockTest lockTest){this.lockTest = lockTest;}@Overridepublic void run(){while(true){lockTest.consume();}}}




0 0
原创粉丝点击