本篇內(nèi)容主要講解“Condition.await, signal 與 Object.wait, notify有什么區(qū)別”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Condition.await, signal 與 Object.wait, notify有什么區(qū)別”吧!
創(chuàng)新互聯(lián)建站專注于銅鼓企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開發(fā),商城網(wǎng)站定制開發(fā)。銅鼓網(wǎng)站建設(shè)公司,為銅鼓等地區(qū)提供建站服務(wù)。全流程定制制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)
Object 類中 wait,notify 與 notifyAll 方法可以用來實(shí)現(xiàn)線程之間的調(diào)度,比如在阻塞隊(duì)列(BlockingQueue)的實(shí)現(xiàn)中,如果隊(duì)列為空,則所有消費(fèi)者線程進(jìn)行阻塞 ( wait ),如果某一個(gè)時(shí)刻隊(duì)列中新添加了一個(gè)元素,則需要喚醒某個(gè)或所有阻塞狀態(tài)的消費(fèi)者線程( notify,notifyAll ),同理如果是隊(duì)列已滿,則所有生產(chǎn)者線程都需要阻塞,等到某個(gè)元素被消費(fèi)之后又需要喚醒某個(gè)或所有正在阻塞的生產(chǎn)者線程
Condition 的 await,signal, singalAll 與 Object 的 wait, notify, notifyAll 都可以實(shí)現(xiàn)的需求,兩者在使用上也是非常類似,都需要先獲取某個(gè)鎖之后才能調(diào)用,而不同的是 Object wait,notify 對(duì)應(yīng)的是 synchronized 方式的鎖,Condition await,singal 則對(duì)應(yīng)的是 ReentrantLock (實(shí)現(xiàn) Lock 接口的鎖對(duì)象)對(duì)應(yīng)的鎖
來看下面具體的示例:使用 wait, notify 和 await, signal 方式分別實(shí)現(xiàn)一個(gè)簡(jiǎn)單的隊(duì)列
public interface SimpleQueueDemo<E> { void put(E e); E take(); }
基于 Object wait, notify 的實(shí)現(xiàn)
public class SynchronizedQueue<E> implements SimpleQueueDemo<E> { private Object[] array; private int index = 0; public SynchronizedQueue(int size) { array = new Object[size]; } @Override public synchronized void put(E item) { while(isFull()) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } array[index++] = item; this.notifyAll(); } @Override @SuppressWarnings("unchecked") public synchronized E take() { while(isEmpty()) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } E item = (E) array[0]; array = Arrays.copyOfRange(array, 1, array.length + 1); array[array.length - 1] = null; index--; this.notifyAll(); return item; } private boolean isFull() { return index >= array.length; } private boolean isEmpty() { return index <= 0; } }
基于 await, signal 的實(shí)現(xiàn)
public class ConditionQueue<E> implements SimpleQueueDemo<E> { private Object[] array; private int index = 0; private static ReentrantLock lock = new ReentrantLock(); private static Condition notEmpty = lock.newCondition(); private static Condition notFull = lock.newCondition(); public ConditionQueue(int size) { this.array = new Object[size]; } @Override public void put(E item) { lock.lock(); try { while(isFull()) { notFull.await(); } array[index++] = item; notEmpty.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } @Override @SuppressWarnings("unchecked") public E take() { lock.lock(); try { while(isEmpty()) { notEmpty.await(); } E item = (E) array[0]; array = Arrays.copyOfRange(array, 1, array.length + 1); array[array.length - 1] = null; index--; notFull.signal(); return item; } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } return null; } private boolean isFull() { return index >= array.length; } private boolean isEmpty() { return index <= 0; } }
兩者在使用形式和實(shí)現(xiàn)的功能上都非常的類似,但這里面有一個(gè)最大的問題就是 synchronized 方式對(duì)應(yīng)的 wait, notify 不能有多個(gè)謂詞條件,Lock 對(duì)應(yīng)的 Condition await, signal 則可以有多個(gè)謂詞條件
private static ReentrantLock lock = new ReentrantLock(); private static Condition notEmpty = lock.newCondition(); private static Condition notFull = lock.newCondition();
沒有多個(gè)謂詞條件帶來的問題在于
例如隊(duì)列已滿,所有的生產(chǎn)者現(xiàn)場(chǎng)阻塞,某個(gè)時(shí)刻消費(fèi)者消費(fèi)了一個(gè)元素,則需要喚醒某個(gè)生產(chǎn)者線程,而通過 Object notify 方式喚醒的線程不能確保一定就是一個(gè)生產(chǎn)者線程,因?yàn)?notify 是隨機(jī)喚醒某一個(gè)正在該 synchronized 對(duì)應(yīng)的鎖上面通過 wait 方式阻塞的線程,如果這時(shí)正好還有消費(fèi)者線程也在阻塞中,則很可能喚醒的是一個(gè)消費(fèi)者線程;signalAll 更是會(huì)喚醒所有在對(duì)應(yīng)鎖上通過 wait 方式阻塞的線程,而不管是生產(chǎn)者還是消費(fèi)者線程。
與之不同的 Condition await, signal 方式則可以對(duì)應(yīng)多個(gè)謂詞條件(notEmpty, notFull),可以很方便的實(shí)現(xiàn)讓生產(chǎn)者線程和消費(fèi)者線程分別在不同的謂詞條件上進(jìn)行等待
本例中所有的生產(chǎn)者線程在 notEmpty 謂詞條件上等待,所有的消費(fèi)者線程在 notFull 謂詞條件上等待,當(dāng)隊(duì)列是滿的時(shí)候所有的生產(chǎn)者線程阻塞,添加元素之后則喚醒某個(gè)消費(fèi)者線程,此時(shí)則不用擔(dān)心會(huì)喚醒消費(fèi)者線程
lock.lock(); try { while(isFull()) { // 生產(chǎn)者線程進(jìn)行阻塞 notFull.await(); } array[index++] = item; // 喚醒某個(gè)消費(fèi)者線程 notEmpty.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); }
到此,相信大家對(duì)“Condition.await, signal 與 Object.wait, notify有什么區(qū)別”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
網(wǎng)頁題目:Condition.await,signal與Object.wait,notify有什么區(qū)別
URL鏈接:http://vcdvsql.cn/article42/gjijhc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、定制網(wǎng)站、關(guān)鍵詞優(yōu)化、搜索引擎優(yōu)化、云服務(wù)器、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)