日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java并发编程实战 第14章 构建自定义的同步工具

發(fā)布時(shí)間:2023/12/18 java 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java并发编程实战 第14章 构建自定义的同步工具 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

狀態(tài)依賴性

定義:只有滿足特定的狀態(tài)才能繼續(xù)執(zhí)行某些操作(這些操作依賴于固定的狀態(tài),這些狀態(tài)需要等待別的線程來滿足)。

FutureTask,Semaphroe,BlockingQueue等,都是狀態(tài)依賴性的類。

條件隊(duì)列

條件對(duì)列:條件對(duì)列就是由于不滿足繼續(xù)的條件而被wait操作阻塞的線程隊(duì)列。他們都在等待條件滿足,然后被喚醒。

條件謂詞:狀態(tài)依賴性依賴的前提條件。如BlockingQueue中的isFull,isEmpty等。

條件等待中存在三個(gè)要素:加鎖 + 條件謂詞 + wait方法

wait方法和notify方法

我理解的wait方法:會(huì)釋放鎖+阻塞當(dāng)前線程,放入條件對(duì)列,等待被喚醒,喚醒后,需要重新獲得鎖,獲得鎖之后繼續(xù)執(zhí)行wait那句代碼所在的位置(即使wait在鎖塊的中間代碼部分)。

notify(All)方法:只是喚醒條件隊(duì)列中的線程。但是不釋放鎖。

使用wait notify方法的時(shí)候,一定要持有條件對(duì)列所屬的鎖。

使用輪詢和休眠實(shí)現(xiàn)簡單的狀態(tài)依賴性阻塞

  • while(true)
  • ????????{
  • ????????????//這里不對(duì)循環(huán)上鎖,不然這個(gè)鎖就無法釋放了,不對(duì)休眠上鎖,休眠上鎖,在休眠的時(shí)候別人也無法操作,永遠(yuǎn)都不可能有元素出去
  • ????????????synchronized (this)
  • ????????????{
  • ????????????????//如果隊(duì)列不是滿的,那么就放入元素
  • ????????????????if(!this.isFull())
  • ????????????????{
  • ????????????????????this.doPut(v);
  • ????????????????????return;
  • ????????????????}
  • ????????????}
  • ????????????//否則休眠,退出cpu占用
  • ????????????Thread.sleep(SLEEP_GRANULARITY);
  • ????????}
  • ????}
  • 使用條件隊(duì)列來實(shí)現(xiàn)狀態(tài)依賴性阻塞

    ?

  • public synchronized void put(V v) throws InterruptedException
  • ???{
  • ???????while(this.isFull())
  • ???????{
  • ???????????//這里掛起程序,會(huì)釋放鎖
  • ???????????this.wait();
  • ???????}
  • ???????//如果隊(duì)列不為滿的,那么程序被喚醒之后從新獲取鎖
  • ???????this.doPut(v);
  • ???????//執(zhí)行結(jié)束,喚醒其他隊(duì)列
  • ???????this.notifyAll();
  • ???}
  • 注意上面要使用while。

    對(duì)于監(jiān)視器來說,wait操作產(chǎn)生的線程,都放在這個(gè)監(jiān)視器唯一的條件隊(duì)列里。

    如果使用Lock,可以使用condition來產(chǎn)生不同的條件對(duì)列。

    注意上面的?this.notifyAll();代碼,將會(huì)喚醒這個(gè)監(jiān)視器條件隊(duì)列里所有等待的線程。其實(shí)這里只用喚醒因?yàn)閑mpty阻塞的線程,而不用喚醒因?yàn)閒ull阻塞的線程。

    如果使用?this.notify(),只會(huì)隨機(jī)喚醒一個(gè),如果喚醒的是因?yàn)閒ull堵塞的線程,那么就可能沒有正常喚醒。影響性能,甚至造成活躍性的危險(xiǎn)。

    這種情況下,可以使用Lock和Condition來改造。

  • protected final Lock lock = new ReentrantLock();
  • private final Condition notFull = lock.newCondition();
  • private final Condition notEmpty = lock.newCondition();
  • ?public void put(T x) throws InterruptedException {
  • ????????lock.lock();
  • ????????try {
  • ????????????while (count == items.length)
  • ????????????????notFull.await();
  • ????????????items[tail] = x;
  • ????????????if (++tail == items.length)
  • ????????????????tail = 0;
  • ????????????++count;
  • ????????????notEmpty.signal();
  • ????????} finally {
  • ????????????lock.unlock();
  • ????????}
  • ????}
  • 注意:這里不是signalAll。

    閥門類

    使用閉鎖CountDownLatch,傳入1的時(shí)候可以作為閥門開關(guān)。前提是在其他線程的第一步先執(zhí)行開關(guān)的await。使用開關(guān)的countDown方法就可以打開開關(guān)。

    但是這種閥門,只能打開,不能關(guān)閉。

    使用wait和notifyAll來實(shí)現(xiàn)可重新關(guān)閉的閥門。

    Condition

    注意,由于Condition對(duì)象繼承自O(shè)bject,它也有wait,notify,notifyAll方法,其實(shí)它對(duì)應(yīng)方法名字應(yīng)該是await,signal,signalAll。

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/xiaolang8762400/p/7074721.html

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的Java并发编程实战 第14章 构建自定义的同步工具的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。