最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java并發(fā)編程中構(gòu)建自定義同步工具

 更新時間:2015年04月14日 09:02:13   投稿:junjie  
這篇文章主要介紹了Java并發(fā)編程中構(gòu)建自定義同步工具,本文講解了可阻塞狀態(tài)依賴操作的結(jié)構(gòu)、有界緩存實現(xiàn)基類示例、阻塞實現(xiàn)方式一:拋異常給調(diào)用者、阻塞實現(xiàn)方式二:通過輪詢和休眠、阻塞實現(xiàn)方式三:條件隊列等內(nèi)容,需要的朋友可以參考下

當(dāng)Java類庫沒有提供適合的同步工具時,就需要構(gòu)建自定義同步工具。

可阻塞狀態(tài)依賴操作的結(jié)構(gòu)

復(fù)制代碼 代碼如下:

acquir lock on object state;//請求獲取鎖
while(precondition does not hold){//沒有滿足前提條件
   release lock;//先釋放鎖
   wait until precondition might hold;//等待滿足前提條件
   optionlly fail if interrupted or timeout expires;//因為中斷或者超時執(zhí)行失敗
   reacquire lock;//重新嘗試獲取鎖
}
perform action//執(zhí)行
   release lock;//釋放鎖

有界緩存實現(xiàn)基類示例

復(fù)制代碼 代碼如下:

public class BaseBoundBuffer<V> {
private final V[] buf;
private int tail;
private int head;
private int count;
@SuppressWarnings("unchecked")
public BaseBoundBuffer(int capacity) {
buf = (V[]) new Object[capacity];
}
public synchronized void doPut(V v) {
buf[tail] = v;
if (++tail == buf.length)
tail = 0;
count++;
}
public synchronized V doTake() {
V v = buf[head];

if (++head == buf.length)
head = 0;
count--;
return v;
}
public final synchronized boolean isFull() {
return count == buf.length;
}
public final synchronized boolean isEmpty() {
return count == 0;
}
}

阻塞實現(xiàn)方式一:拋異常給調(diào)用者

復(fù)制代碼 代碼如下:

public synchronized void put1(V v)  throws Exception{
if(isFull())
throw new Exception("full error");
doPut(v);
}

分析:異常應(yīng)該應(yīng)用于發(fā)生異常情況中,在這里拋異常不合適;需要調(diào)用者是處理前提條件失敗的情況,并沒有解決根本問題。
阻塞實現(xiàn)方式二:通過輪詢和休眠
復(fù)制代碼 代碼如下:

public void put2(V v) throws InterruptedException {
while (true) {//輪詢
synchronized (this) {
if (!isFull()) {
doPut(v);
return;    
}
}
Thread.sleep(SLEEP_TIME);//休眠
}
}

分析:很難權(quán)衡休眠時間SLEEP_TIME設(shè)置。如果設(shè)置過小,CPU可能會輪詢多次,消耗CPU資源也越高;如果設(shè)置過大,響應(yīng)性就越低。

阻塞實現(xiàn)方式三:條件隊列

條件隊列中的元素是一個個等待相關(guān)條件的線程。每個Java對象都可以作為一個鎖,每個對象同樣可以作為一個條件隊列,并且Object中的wait、notify、notifyAll方法就構(gòu)成了內(nèi)部條件隊列的API。Object.wait會自動釋放鎖,并請求操作系統(tǒng)掛起當(dāng)前線程,從而使其它線程能獲得這個鎖并修改對象的狀態(tài)。Object.notify和Object.notifyAll能喚醒正在等待線程,從條件隊列中選取一個線程喚醒并嘗試重新獲取鎖。

復(fù)制代碼 代碼如下:

public synchronized void put3(V v) throws InterruptedException {
while(isFull())
wait();
doput(v);
notifyAll();
}

分析:獲得較好響應(yīng),簡單易用。

使用條件隊列​
1.條件謂詞

1).定義:條件謂詞是使某個操作成為狀態(tài)依賴操作的前提條件。條件謂詞是由類中各個狀態(tài)變量構(gòu)成的表達式。例如,對于put方法的條件謂詞就是“緩存不為空”。
2).關(guān)系:在條件等待中存在一種重要的三元關(guān)系,包括加鎖、wait方法和一個條件謂詞。在條件謂詞中包含多個狀態(tài)變量,而每個狀態(tài)變量必須由一個鎖來保護,因此在測試條件謂詞之前必須先持有這個鎖。鎖對象和條件隊列對象(及調(diào)用wait和notify等方法所在的對象)必須是同一個對象。
3).約束:每次調(diào)用wait都會隱式地和特定的條件謂詞相關(guān)聯(lián),當(dāng)調(diào)用特定條件謂詞時,調(diào)用者必須已經(jīng)持有與條件隊列相關(guān)的鎖,這個鎖必須還保護這組成條件謂詞的狀態(tài)變量

2.條件隊列使用規(guī)則

1).通常都有一個條件謂詞
2).永遠(yuǎn)在調(diào)用wait之前測試條件謂詞,并且在wait中返回后再次測試;
3).永遠(yuǎn)在循環(huán)中調(diào)用wait;
4).確保構(gòu)成條件謂詞的狀態(tài)變量被鎖保護,而這個鎖必須與這個條件隊列相關(guān)聯(lián);
5).當(dāng)調(diào)用wait、notify和notifyAll時,要持有與條件隊列相關(guān)聯(lián)的鎖;
6).在檢查條件謂詞之后,開始執(zhí)行被保護的邏輯之前,不要釋放鎖;

3.通知

盡量使用notifyAll,而不是nofify.因為nofify會隨機喚醒一個線程從休眠狀態(tài)變?yōu)锽locked狀態(tài)(Blocked狀態(tài)是種線程一直處于嘗試獲取鎖的狀態(tài),即一旦發(fā)現(xiàn)鎖可用,馬上持有鎖),而notifyAll會喚醒條件隊列中所有的線程從休眠狀態(tài)變?yōu)锽locked狀態(tài).考慮這么種情況,假如線程A因為條件謂詞Pa進入休眠狀態(tài),線程B因為條件謂詞Pb進入休眠狀態(tài).這時Pb為真,線程C執(zhí)行單一的notify.如果JVM隨機選擇了線程A進行喚醒,那么線程A檢查條件謂詞Pa不為真后又進入了休眠狀態(tài).從這以后再也沒有其它線程能被喚醒,程序會一直處于休眠狀態(tài).如果使用notifyAll就不一樣了,JVM會喚醒條件隊列中所有等待線程從休眠狀態(tài)變?yōu)锽locked狀態(tài),即使隨機選出一個線程一因為條件謂詞不為真進入休眠狀態(tài),其它線程也會去競爭鎖從而繼續(xù)執(zhí)行下去.

4.狀態(tài)依賴方法的標(biāo)準(zhǔn)形式

復(fù)制代碼 代碼如下:

void stateDependentMethod throwsInterruptedException{
synchronized(lock){
while(!conditionPredicate))
lock.wait();
}
//dosomething();
....

notifyAll();
}

顯示Condition對象

顯示的Condition對象是一種更靈活的選擇,提供了更豐富的功能:在每個鎖上可以存在多個等待,條件等待可以是中斷的獲不可中斷的,基于時限的等待,以及公平的或非公平的隊列操作。一個Condition可以和一個Lock關(guān)聯(lián)起來,就像一個條件隊列和一個內(nèi)置鎖關(guān)聯(lián)起來一樣。要創(chuàng)建一個Condition,可以在相關(guān)聯(lián)的Lock上調(diào)用Lock.newCondition方法。以下用顯示條件變量重新實現(xiàn)有界緩存

復(fù)制代碼 代碼如下:

public class ConditionBoundedBuffer<V> {
 private final V[] buf;
 private int tail;
 private int head;
 private int count;
 private Lock lock = new ReentrantLock();
 private Condition notFullCondition = lock.newCondition();
 private Condition notEmptyCondition = lock.newCondition();
 @SuppressWarnings("unchecked")
 public ConditionBoundedBuffer(int capacity) {
  buf = (V[]) new Object[capacity];
 }

 public void doPut(V v) throws InterruptedException {
  try {
   lock.lock();
   while (count == buf.length)
    notFullCondition.await();
   buf[tail] = v;
   if (++tail == buf.length)
    tail = 0;
   count++;
   notEmptyCondition.signal();
  } finally {
   lock.unlock();
  }

 }

 public V doTake() throws InterruptedException {
  try {
   lock.lock();
   while (count == 0)
    notEmptyCondition.await();
   V v = buf[head];
   buf[head] = null;
   if (++head == buf.length)
    head = 0;
   count--;
   notFullCondition.signal();
   return v;
  } finally {
   lock.unlock();
  }
 }
}

相關(guān)文章

  • java8?stream排序以及自定義比較器方式

    java8?stream排序以及自定義比較器方式

    這篇文章主要介紹了java8?stream排序以及自定義比較器方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring中@order注解用法實戰(zhàn)教程

    Spring中@order注解用法實戰(zhàn)教程

    @Order注解主要用來控制配置類的加載順序,數(shù)字越小,越先加載,下面這篇文章主要給大家介紹了關(guān)于Spring中@order注解用法的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • mybatis@insert?注解如何判斷insert或是update

    mybatis@insert?注解如何判斷insert或是update

    這篇文章主要介紹了mybatis@insert?注解如何判斷insert或是update,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Tomcat服務(wù)無法啟動的問題的解決方法

    Tomcat服務(wù)無法啟動的問題的解決方法

    這篇文章主要介紹了Tomcat服務(wù)無法啟動的問題的解決方法,需要的朋友可以參考下
    2014-02-02
  • SpringBoot配置文件密碼加密的三種方案

    SpringBoot配置文件密碼加密的三種方案

    這篇文章主要介紹了SpringBoot配置文件密碼加密的三種方案,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-04-04
  • java實現(xiàn)注冊登錄系統(tǒng)

    java實現(xiàn)注冊登錄系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)注冊登錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • java 定時器線程池(ScheduledThreadPoolExecutor)的實現(xiàn)

    java 定時器線程池(ScheduledThreadPoolExecutor)的實現(xiàn)

    這篇文章主要介紹了java 定時器線程池(ScheduledThreadPoolExecutor),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • SpringBoot中如何解決讀取properties文件讀取問題

    SpringBoot中如何解決讀取properties文件讀取問題

    這篇文章主要介紹了SpringBoot中如何解決讀取properties文件讀取問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 超好用的Java工具類庫Hutool用法詳解

    超好用的Java工具類庫Hutool用法詳解

    Hutool是一個小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關(guān)API的學(xué)習(xí)成本,提高工作效率,下面就跟隨小編一起來學(xué)習(xí)一下Hutool的具體用法吧
    2023-09-09
  • Java的Struts框架簡介與環(huán)境配置教程

    Java的Struts框架簡介與環(huán)境配置教程

    這篇文章主要介紹了Java的Struts框架與其環(huán)境配置教程,Struts框架是Java注明的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-11-11

最新評論

虞城县| 抚顺市| 囊谦县| 湟源县| 舞钢市| 延安市| 水城县| 江达县| 聂拉木县| 交口县| 修水县| 岳池县| 凤山县| 昌宁县| 桐梓县| 陆河县| 波密县| 竹溪县| 虹口区| 安新县| 冷水江市| 开平市| 威宁| 双江| 荣昌县| 崇左市| 沽源县| 溆浦县| 喀喇| 宜丰县| 商洛市| 桃园县| 梅州市| 阿坝| 宝应县| 榆林市| 科技| 莱州市| 宣汉县| 敦煌市| 和平区|