中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

為什么 要建設(shè)網(wǎng)站掃一掃識(shí)別圖片

為什么 要建設(shè)網(wǎng)站,掃一掃識(shí)別圖片,長(zhǎng)春 建設(shè)工程信息網(wǎng)站,做個(gè)網(wǎng)站多少錢找誰(shuí)做文章目錄一 . synchronized 原理1.1 synchronized 使用的鎖策略1.2 synchronized 是怎樣自適應(yīng)的? (鎖膨脹 / 升級(jí) 的過(guò)程)1.3 synchronized 其他的優(yōu)化操作鎖消除鎖粗化1.4 常見面試題二 . JUC (java.util.concurrent)2.1 Callable 接口2.2 ReentrantLock2.3 原子類2.4 線程池…

文章目錄

  • 一 . synchronized 原理
    • 1.1 synchronized 使用的鎖策略
    • 1.2 synchronized 是怎樣自適應(yīng)的? (鎖膨脹 / 升級(jí) 的過(guò)程)
    • 1.3 synchronized 其他的優(yōu)化操作
      • 鎖消除
      • 鎖粗化
    • 1.4 常見面試題
  • 二 . JUC (java.util.concurrent)
    • 2.1 Callable 接口
    • 2.2 ReentrantLock
    • 2.3 原子類
    • 2.4 線程池
      • ExecutorService 和 Executors

大家好 , 這篇文章給大家分享多線程中 synchronized 的原理以及 JUC 相關(guān)問(wèn)題
注意這塊的 synchronized 是小寫的 , 一定要注意拼寫
推薦大家跳轉(zhuǎn)到 此鏈接 查看效果更佳~
上一篇文章的鏈接我也給大家貼到這里了
點(diǎn)擊即可跳轉(zhuǎn)到文章專欄~
在這里插入圖片描述

一 . synchronized 原理

注意這塊的 synchronized 是小寫的 , 一定要注意拼寫

1.1 synchronized 使用的鎖策略

  1. 既是悲觀鎖 , 也是樂(lè)觀鎖 (自適應(yīng)鎖)
  2. 既是輕量級(jí)鎖 , 也是重量級(jí)鎖 (自適應(yīng)鎖)
  3. 輕量級(jí)鎖部分基于自旋鎖實(shí)現(xiàn) , 重量級(jí)鎖部分基于掛起等待鎖來(lái)實(shí)現(xiàn)
  4. 不是讀寫鎖
  5. 是非公平鎖
  6. 是可重入鎖

1.2 synchronized 是怎樣自適應(yīng)的? (鎖膨脹 / 升級(jí) 的過(guò)程)

synchronized 在加鎖的時(shí)候要經(jīng)歷幾個(gè)階段 :

  1. 無(wú)鎖 (沒(méi)加鎖)
  2. 偏向鎖 (剛開始加鎖 , 未產(chǎn)生競(jìng)爭(zhēng)的時(shí)候)
  3. 輕量級(jí)鎖 (產(chǎn)生鎖競(jìng)爭(zhēng)了)
  4. 重量級(jí)鎖 (鎖競(jìng)爭(zhēng)的更激烈了)

其中 , 我們?cè)俜治鲆幌率裁词瞧蜴i
偏向鎖 , 不是"真正加鎖" , 只是用個(gè)標(biāo)記表示 “這個(gè)鎖是我的了” , 在遇到其他線程來(lái)競(jìng)爭(zhēng)鎖之前 , 都始終保持這個(gè)狀態(tài) .
直到真的有人來(lái)競(jìng)爭(zhēng)了,此時(shí)才真的加鎖
這個(gè)過(guò)程類似于單例模式中的"懶漢模式" , 必要的時(shí)候再加鎖 , 節(jié)省開銷

舉個(gè)栗子 :
我是一個(gè)漂亮的妹子 , 遇到了一個(gè)小哥哥 , 對(duì)他各個(gè)方面都很滿意 , 我們的感情就很快升溫
但是我就不和他確定關(guān)系 , 造成若即若離的感覺(jué) , 這樣的話后面如果我膩歪了 , 隨時(shí)伸腿就踹了 , 成本很低
這就是偏向鎖狀態(tài)

突然 , 我又發(fā)現(xiàn)另外一個(gè)妹子也在接近小哥哥 , 這個(gè)時(shí)候我趁著他們倆剛認(rèn)識(shí) , 我就趕緊和小哥哥確立男女朋友關(guān)系 , 并且發(fā)朋友圈官宣 , 另外的這個(gè)妹子就上一邊等著去
這就是偏向鎖在遇到鎖競(jìng)爭(zhēng)的時(shí)候 , 再真正進(jìn)行加鎖

如果沒(méi)有額外的妹子(線程)過(guò)來(lái)競(jìng)爭(zhēng) , 從始至終都是在偏向鎖的狀態(tài) , 也就省去了加鎖以及解鎖的開銷了 , 這就更加的輕量

1.3 synchronized 其他的優(yōu)化操作

鎖消除

鎖消除.編譯器自動(dòng)判定 , 如果認(rèn)為這個(gè)代碼沒(méi)必要加鎖 , 就不加了 .
這個(gè)操作不是所有情況下都會(huì)觸發(fā) , 大部分情況下不能觸發(fā)
比如 :

StringBuffer sb = new StringBuffer();
sb.append("a");
sb.append("b");
sb.append("c");
sb.append("d");

此處的這幾個(gè) append 方法 , 內(nèi)部都是帶有 synchronized 的
如果上述代碼都是在同一個(gè)線程中運(yùn)行的 , 此時(shí)就沒(méi)必要再去加鎖了
JVM 就悄悄地把鎖去掉了

鎖粗化

先了解鎖的粒度 : synchronized 包含的代碼范圍是大還是小 , 范圍越大 , 粒度越粗 ; 范圍越小 , 粒度越細(xì)
鎖的粒度細(xì)了 , 能夠更好的提高線程的并發(fā) , 但會(huì)也會(huì)增加 “加鎖解鎖” 的次數(shù)
image.png
image.png

1.4 常見面試題

  1. 能夠理解 synchronized 基本執(zhí)行過(guò)程 , 理解鎖對(duì)象 , 理解鎖競(jìng)爭(zhēng)
  2. 能夠知道 synchronized 的基本策略
  3. 能夠理解 synchronized 內(nèi)部的一些鎖優(yōu)化的過(guò)程 ( 鎖升級(jí) , 鎖消除 , 鎖粗化 )
  4. 什么是偏向鎖

二 . JUC (java.util.concurrent)

concurrent 中文叫做并發(fā)
java.util.concurrent 這個(gè)包里就存放了很多和多線程開發(fā)相關(guān)的類

2.1 Callable 接口

和我們之前學(xué)習(xí)過(guò)得 Runnable 非常類似 , 都是可以在創(chuàng)建線程的時(shí)候 , 來(lái)指定一個(gè) “具體的任務(wù)”
而 Callable 指定的任務(wù)是帶有返回值的 , Runnable 是不帶返回值的
Callable 里面會(huì)提供一個(gè) call 方法 , call 方法是帶有返回值的 , 我們可以借助它很容易的獲得到任務(wù)的執(zhí)行結(jié)果

舉個(gè)栗子 : 創(chuàng)建線程計(jì)算 1 + 2 + 3 + … + 1000, 不使用 Callable 版本

static class Result {public int sum = 0;public Object lock = new Object();
}public static void main(String[] args) throws InterruptedException {Result result = new Result();// 創(chuàng)建一個(gè)線程去計(jì)算 1~100 之間的值// 但是我們通過(guò) run 方法沒(méi)辦法返回值// 就需要把結(jié)果寫入到 Result 類當(dāng)中的 sum Thread t = new Thread() {@Overridepublic void run() {int sum = 0;for (int i = 1; i <= 1000; i++) {sum += i;}// 賦值操作需要加鎖synchronized (result.lock) {result.sum = sum;result.lock.notify();}}};t.start();// 在主線程這里,再去針對(duì) result 結(jié)果進(jìn)行等待// 上面的 result 結(jié)果計(jì)算好之后,上面的 notify 就會(huì)喚醒下面的 wait// 打印 sum 的值synchronized (result.lock) {while (result.sum == 0) {result.lock.wait();}System.out.println(result.sum);}
}

上述代碼需要一個(gè)輔助類 Result , 還需要使用一系列的加鎖和 wait notify 操作 , 代碼復(fù)雜 , 容易出錯(cuò) .
我們可以使用 Callable 接口

import java.util.concurrent.Callable;public class Demo28 {public static void main(String[] args) {// 創(chuàng)建 Callable 接口,它是帶有泛型參數(shù)的// 這個(gè)泛型參數(shù)實(shí)際就是 call 方法的返回值// new 一個(gè)匿名內(nèi)部類Callable<Integer> callable = new Callable<Integer>() {// 這里的 Object 要改成 Integer@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i <= 1000; i++) {sum += i;}return sum;}};}
}

接下來(lái) , 我們就可以新建線程執(zhí)行這個(gè)任務(wù)了
image.png

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class Demo28 {public static void main(String[] args) throws ExecutionException, InterruptedException {// 創(chuàng)建 Callable 接口,它是帶有泛型參數(shù)的// 這個(gè)泛型參數(shù)實(shí)際就是 call 方法的返回值// new 一個(gè)匿名內(nèi)部類Callable<Integer> callable = new Callable<Integer>() {// 這里的 Object 要改成 Integer@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i <= 1000; i++) {sum += i;}return sum;}};// 套上一層,目的是為了獲取到后續(xù)的結(jié)果FutureTask<Integer> task = new FutureTask<>(callable);Thread t = new Thread(task);t.start();// 在線程 t 執(zhí)行結(jié)束之前,get 會(huì)阻塞等待,直到 t 執(zhí)行完了,結(jié)果算完了// get 才能返回.返回值就是 call 方法 return 的內(nèi)容System.out.println(task.get());}
}

這里的 FutureTask 就好比 :
我們?nèi)ゲ宛^吃飯 , 人很多的時(shí)候 , 老板會(huì)給你個(gè)小票 , 后續(xù)就可以憑小票來(lái)取餐


到目前為止 , 我們已經(jīng)學(xué)習(xí)過(guò)好幾種創(chuàng)建線程的方式了

  1. 繼承 Thread
  2. 使用 Runnable
  3. 使用 lambda
  4. 使用 Callable
  5. 使用線程池

2.2 ReentrantLock

ReentrantLock 代表可重入鎖

synchronized 已經(jīng)是可重入鎖了 , 為什么還要再弄一個(gè) ReentrantLock 呢 ?

  1. synchronized 是單純的關(guān)鍵字 , 以代碼塊為單位進(jìn)行加鎖解鎖 .

ReentrantLock則是一個(gè)類 , 提供 lock 方法加鎖 , unlock 方法解鎖

import java.util.concurrent.locks.ReentrantLock;public class Demo29 {public static void main(String[] args) {ReentrantLock locker = new ReentrantLock();// 加鎖locker.lock();// 其他代碼邏輯// 解鎖locker.unlock();}
}

但這種方式還存在一些問(wèn)題
假如中間的其他代碼邏輯出現(xiàn)了問(wèn)題 , 拋出了異常 , 后面的 unlock() 就執(zhí)行不到了
所以我們一般把加鎖解鎖操作放到 try catch finally 中

import java.util.concurrent.locks.ReentrantLock;public class Demo29 {public static void main(String[] args) {ReentrantLock locker = new ReentrantLock();try {// 加鎖locker.lock();// 其他代碼邏輯} finally {// 解鎖locker.unlock();}}
}
  1. ReentrantLock 會(huì)提供一個(gè)"公平鎖"版本 , 在構(gòu)造實(shí)例的時(shí)候 , 可以通過(guò)構(gòu)造方法指定一個(gè)參數(shù) , 切換到公平鎖模式

ReentrantLock locker = new ReentrantLock(true);
synchronized 只是一個(gè)非公平鎖

  1. ReentrantLock 還提供了一個(gè)特殊的加鎖操作 : tryLock()

默認(rèn)的 lock 是加鎖失敗 , 就阻塞
而 tryLock 加鎖失敗 , 則不阻塞 , 直接往下執(zhí)行 , 并且返回 false
除了立即失敗之外 , tryLock 還能設(shè)定一定的等待時(shí)間 (等一會(huì)再失敗)

  1. ReentrantLock 提供了更強(qiáng)大的 等待/喚醒 機(jī)制

synchronized 搭配的是 Object.wait / notify , 喚醒的時(shí)候 , 隨機(jī)喚醒其中一個(gè)
ReentrantLock 搭配了 Condition 類來(lái)實(shí)現(xiàn)等待喚醒 , 可以做到能隨機(jī)喚醒一個(gè) , 也能指定線程喚醒

大部分情況下 , 使用鎖還是 synchronized 為主 .
特殊場(chǎng)景下 , 才使用 ReentrantLock

2.3 原子類

原子類內(nèi)部用的是 CAS 實(shí)現(xiàn),所以性能要比加鎖實(shí)現(xiàn) i++ 高很多
我們常用的是 AtomicInteger
他的常用方法有

addAndGet(int delta);   i += delta;
decrementAndGet(); 		--i;
getAndDecrement(); 		i--;
incrementAndGet(); 		++i;
getAndIncrement(); 		i++;

2.4 線程池

雖然創(chuàng)建銷毀線程比創(chuàng)建銷毀進(jìn)程更輕量 , 但是在頻繁創(chuàng)建銷毀線程的時(shí)候還是會(huì)比較低效.
線程池就是為了解決這個(gè)問(wèn)題 . 如果某個(gè)線程不再使用了 , 并不是真正把線程釋放 , 而是放到一個(gè) "池子"中 , 下次如果需要用到線程就直接從池子中取 , 不必通過(guò)系統(tǒng)來(lái)創(chuàng)建了.

ExecutorService 和 Executors

ExecutorService 是一個(gè)線程實(shí)例 , Executors 是一個(gè)工廠類

Executors 創(chuàng)建線程池的幾種方式

  • newFixedThreadPool : 創(chuàng)建固定線程數(shù)的線程池
  • newCachedThreadPool : 創(chuàng)建線程數(shù)目動(dòng)態(tài)增長(zhǎng)的線程池.
  • newSingleThreadExecutor : 創(chuàng)建只包含單個(gè)線程的線程池.
  • newScheduledThreadPool : 設(shè)定 延遲時(shí)間后執(zhí)行命令 , 或者定期執(zhí)行命令 . 是進(jìn)階版的 Timer.

Executors 本質(zhì)上是 ThreadPoolExecutor 類的封裝 , 這個(gè)類是標(biāo)準(zhǔn)庫(kù)中最核心的線池類
打開我們的 Java 文檔
image.png
我們來(lái)看第四個(gè)構(gòu)造方法
image.png
實(shí)際工作中 , 一般建議大家 , 使用線程池的時(shí)候 , 盡量還是用 ThreadPoolExecutor 復(fù)雜版本的 , 這里的參數(shù)都顯式的手動(dòng)傳參 , 這樣就可以更好的掌控代碼

當(dāng)我們使用線程池的時(shí)候 , 線程數(shù)目設(shè)置成多少合適 ?
只要你回答出具體的數(shù)字 , 一定都是錯(cuò)的 .
不同的場(chǎng)景 , 不同的程序 , 不同的主機(jī)配置 , 都會(huì)有差異
面試中我們回答不了具體設(shè)置幾個(gè)線程 , 但是可以回答 : 找到合適線程數(shù)的方法 -> 壓測(cè)(性能測(cè)試)
針對(duì)當(dāng)前的程序進(jìn)行性能測(cè)試 , 分別設(shè)置不同的線程數(shù)目 , 分別進(jìn)行測(cè)試
在測(cè)試過(guò)程中 , 會(huì)記錄程序的時(shí)間、CPU占用、內(nèi)存占用…
根據(jù)壓測(cè)結(jié)果 , 來(lái)選擇咱們覺(jué)得最適合當(dāng)前場(chǎng)景的數(shù)目


關(guān)于 JUC , 我們后續(xù)還會(huì)再增加一些內(nèi)容 , 大家敬請(qǐng)期待~
如果對(duì)你有幫助的話 , 請(qǐng)一鍵三連嗷~
在這里插入圖片描述

http://www.risenshineclean.com/news/54370.html

相關(guān)文章:

  • 網(wǎng)站制作策劃書最新域名8xgmvxyz
  • 長(zhǎng)春專業(yè)做網(wǎng)站公司排名手機(jī)優(yōu)化大師官方版
  • 網(wǎng)站通欄南京seo網(wǎng)站管理
  • 基于jsp網(wǎng)站開發(fā)與實(shí)現(xiàn)和生活app下載安裝最新版
  • 好用的免費(fèi)建站網(wǎng)站百度網(wǎng)絡(luò)營(yíng)銷中心
  • 在靜安正規(guī)的設(shè)計(jì)公司網(wǎng)站個(gè)人博客登錄入口
  • 卡通網(wǎng)站建設(shè)濟(jì)南頭條新聞熱點(diǎn)
  • 正規(guī)的培訓(xùn)行業(yè)網(wǎng)站開發(fā)seo關(guān)鍵詞如何布局
  • 在中國(guó)做博彩網(wǎng)站違法嗎seo網(wǎng)站優(yōu)化服務(wù)商
  • wap asp網(wǎng)站模板下載淘寶怎樣優(yōu)化關(guān)鍵詞
  • 個(gè)人網(wǎng)站建立教程網(wǎng)站建設(shè)黃頁(yè)免費(fèi)觀看
  • 網(wǎng)站建設(shè)最好的公司網(wǎng)站域名費(fèi)一年多少錢
  • 廣州網(wǎng)站優(yōu)化關(guān)鍵詞排名最新疫情新聞100字
  • 長(zhǎng)治制作公司網(wǎng)站的公司百度免費(fèi)推廣怎么操作
  • 可以做來(lái)電名片的網(wǎng)站seo高端培訓(xùn)
  • 怎么做網(wǎng)站首頁(yè)圖片不會(huì)失真云南今日頭條新聞
  • 內(nèi)容管理系統(tǒng)開源佛山網(wǎng)站建設(shè)十年樂(lè)云seo
  • 一個(gè)好的網(wǎng)站應(yīng)該具有什么西安百度推廣競(jìng)價(jià)托管
  • 舉例說(shuō)明網(wǎng)絡(luò)營(yíng)銷的概念小紅書seo排名帝搜軟件
  • 網(wǎng)站建設(shè)商務(wù)的術(shù)語(yǔ)怎么注冊(cè)網(wǎng)站平臺(tái)
  • wordpress安裝顯示404寧波優(yōu)化網(wǎng)站排名軟件
  • 可信賴的深圳網(wǎng)站建設(shè)百度seo霸屏軟件
  • 門戶網(wǎng)站建設(shè)方案文檔如何自己建立一個(gè)網(wǎng)站
  • 京東商城企業(yè)網(wǎng)站建設(shè)分析收錄網(wǎng)
  • 網(wǎng)站內(nèi)的搜索怎么做的市場(chǎng)調(diào)研問(wèn)卷
  • 網(wǎng)站標(biāo)題寫什么作用seo顧問(wèn)服務(wù) 樂(lè)云踐新專家
  • 做了個(gè)網(wǎng)站 怎么做seo百度網(wǎng)盤網(wǎng)頁(yè)版登錄首頁(yè)
  • 空間網(wǎng)站鏈接怎么做淘寶店鋪買賣交易平臺(tái)
  • seo優(yōu)化方案書鄭州seo優(yōu)化推廣
  • 做網(wǎng)站-信科網(wǎng)絡(luò)軟文推廣網(wǎng)