逐梦少年,看你能不能发现宝藏(16)


阻塞队列用在哪里?====》对应着生产者和消费者 。一种是传统版本的生产者消费者,一种是阻塞队列版生产者消费者
上面,左边的是老的生产者消费者模式,右边是对应的新的lock锁的,生产者消费者模式 。===》都是传统的写法
class ShareData {//资源类private int number = 0;private Lock lock =new ReentrantLock();private Condition condition = lock.newCondition();public void increment()throws Exception {lock.lock();try{//1.判断while (number != 0) {//等待,不能生产condition.await();}//2.干活number++;System.out.println(Thread.currentThread().getName()+"\t" +number);//3.通知唤醒condition.signalAll();}catch(Exception e){e.printStackTrace();}finally{lock.unlock();}}public void decrement()throws Exception {lock.lock();try{//1.判断while (number == 0) {//等待,不能生产condition.await();}//2.干活number--;System.out.println(Thread.currentThread().getName()+"\t" +number);//3.通知唤醒condition.signalAll();}catch(Exception e){e.printStackTrace();}finally{lock.unlock();}}}/** 题目:一个初始值为零的变量,两个线程对其交替操作,一个加1一个减1,来5轮** 1线程操作(方法)资源类* 2判断干活通知* 3防止虚假唤醒机制* */public class ProdConsumer {public static void main(String[] args) {ShareData shareData = http://www.kingceram.com/post/new ShareData();new Thread(()->{for (int i = 1; i <= 5; i++) {try {shareData.increment();} catch (Exception e) {e.printStackTrace();}}},"AAA").start();new Thread(()->{for (int i = 1; i <= 5; i++) {try {shareData.decrement();} catch (Exception e) {e.printStackTrace();}}},"BBB").start();}}
30.和Lock有什么区别?用新的lock有什么好处?请举例说明 。
1.原始构成
? 是关键字属于JVM层面 。
? 底层是(进入)(底层是通过对象来完成的,其实wait/等方法也依赖于对象只有在同步块或方法中才能调用wait/等方法)
?
拓展:注意当你使用关键字的时候,底层的编译里面是只有一个,但却有两个,为什么呢?,因为是可重入锁,两个,当发生异常时,一个退出起作用,最后相当于再放开一次,确保对象的释放,这样避免产生死锁 。
? Lock是具体类(java.util..Locks.lock)是api层面的锁 。
2.使用方法
? 不需要用户去手动释放锁,当代码执行完后系统会让线程释放对象锁的占用 。
? 则需要用户去手动释放锁若没有主动释放锁,就有可能导致出现死锁现象 。
? 需要Lock()和()方法配合try/语句块来完成 。
3.等待是否可中断
? 不可中断,除非抛出异常或者正常运行完成
? 可中断 。1.设置超时方法(long ,unit)
? 2.()放代码块中,调用()方法可中断 。
4.加锁是否公平
? 非公平锁
? 两者都可以,默认非公平锁,构造方法可以传入值,true为公平锁,false为非公平锁
锁绑定多个条件
没有
用了实现分组唤醒需要唤醒的线程们,可以精确唤醒,而不是像要么随机唤醒一个线程,要么唤醒全部线程 。
/** 题目: 多线程之间按顺序调用,实现A -》 B -》 C三个线程启动,要求如下:* AA打印5次,BB打印10次,CC打印15次* 紧接着* AA打印5次,BB打印10次,CC打印15次*。。* */class ShareResoure {private int number = 1;//A:1,B:2,C:3private Lock lock = new ReentrantLock();private Condition c1 = lock.newCondition();private Condition c2 = lock.newCondition();private Condition c3 = lock.newCondition();public void print5() {lock.lock();try {//1.判断,为了避免虚假唤醒,的用while进行判断while (number != 1) {c1.await();}//2.干活for (int i = 1; i <= 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}//3.通知B线程,number = 2;c2.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void print10() {lock.lock();try {//1.判断,为了避免虚假唤醒,的用while进行判断while (number != 2) {c2.await();}//2.干活for (int i = 1; i