③. 使用ReentrantLock实现 (显示锁)
- ①. ReentrantLock( ):创建一个ReentrantLock的实例
- ②. void lock( ):获得锁
- ③. void unlock( ):释放锁
/* * 使用Lock代替Synchronized来实现新版的生产者和消费者模式 ! * */ @SuppressWarnings("all") public class ThreadWaitNotifyDemo { public static void main(String[] args) { AirCondition airCondition=new AirCondition(); new Thread(()->{ for (int i = 0; i <10 ; i++) airCondition.decrement();},"线程A").start(); new Thread(()->{ for (int i = 0; i <10 ; i++) airCondition.increment();},"线程B").start(); new Thread(()->{ for (int i = 0; i <10 ; i++) airCondition.decrement();},"线程C").start(); new Thread(()->{ for (int i = 0; i <10 ; i++) airCondition.increment();},"线程D").start(); } } class AirCondition{ private int number=0; //定义Lock锁对象 final Lock lock=new ReentrantLock(); final Condition condition = lock.newCondition(); //生产者,如果number=0就 number++ public void increment(){ lock.lock(); try { //1.判断 while(number!=0){ try { condition.await();//this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //2.干活 number++; System.out.println(Thread.currentThread().getName()+":\t"+number); //3.唤醒 condition.signalAll();//this.notifyAll(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } //消费者,如果number=1,就 number-- public void decrement(){ lock.lock(); try { //1.判断 while(number==0){ try { condition.await();//this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //2.干活 number--; System.out.println(Thread.currentThread().getName()+":\t"+number); //3.唤醒 condition.signalAll();//this.notifyAll(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } }
④. 精确通知
/* 多个线程之间按顺序调用,实现A->B->C 三个线程启动,要求如下: AA打印5次,BB打印10次,CC打印15次 接着 AA打印5次,BB打印10次,CC打印15次 ....来10轮 * */ public class ThreadOrderAccess { public static void main(String[] args) { ShareResource shareResource=new ShareResource(); new Thread(()->{ for (int i = 1; i <=10; i++)shareResource.print5(); },"线程A").start(); new Thread(()->{ for (int i = 1; i <=10; i++)shareResource.print10(); },"线程B").start(); new Thread(()->{ for (int i = 1; i <=10; i++)shareResource.print15(); },"线程C").start(); } } class ShareResource{ //设置一个标识,如果是number=1,线程A执行... private int number=1; Lock lock=new ReentrantLock(); Condition condition1=lock.newCondition(); Condition condition2=lock.newCondition(); Condition condition3=lock.newCondition(); public void print5(){ lock.lock(); try { //1.判断 while(number!=1){ condition1.await(); } //2.干活 for (int i = 1; i <=5; i++) { System.out.println(Thread.currentThread().getName()+":\t"+i); } //3.唤醒 number=2; condition2.signal(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } public void print10(){ lock.lock(); try { //1.判断 while(number!=2){ condition2.await(); } //2.干活 for (int i = 1; i <=10; i++) { System.out.println(Thread.currentThread().getName()+":\t"+i); } //3.唤醒 number=3; condition3.signal(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } public void print15(){ lock.lock(); try { //1.判断 while(number!=3){ condition3.await(); } //2.干活 for (int i = 1; i <=15; i++) { System.out.println(Thread.currentThread().getName()+":\t"+i); } //3.唤醒 number=1; condition1.signal(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } }