成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

多線程核心要點(diǎn),你知道嗎?

開發(fā) 前端
在 JDK 1.6 引入了兩種新型鎖機(jī)制:偏向鎖和輕量級鎖,它們的引入是為了解決在沒有多線程競爭或基本沒有競爭的場景下因使用傳統(tǒng)鎖機(jī)制帶來的性能開銷問題。

多線程

線程的狀態(tài)。

一、線程池

  1. 提交任務(wù)時(shí) 4 種情況:
  • 小于 corePoolSize addWorker()。
  • 大于 corePoolSize workQueue.offer(command) 直接增加 task 如果增加失敗就拒絕。

  1. 拒絕策略
  • AbortPolicy 拋出異常,默認(rèn)。
  • CallerRunsPolicy 不使用線程池執(zhí)行。
  • DiscardPolicy 直接丟棄。
  • DiscardOldestPolicy 丟棄隊(duì)列中最舊的任務(wù)。

二、鎖

Sychronized 原理

用法:

  • 方法
  • 代碼塊

在 JDK 1.6 之前,synchronized 只有傳統(tǒng)的鎖機(jī)制,因此給開發(fā)者留下了 synchronized 關(guān)鍵字相比于其他同步機(jī)制性能不好的印象。在 JDK 1.6 引入了兩種新型鎖機(jī)制:偏向鎖和輕量級鎖,它們的引入是為了解決在沒有多線程競爭或基本沒有競爭的場景下因使用傳統(tǒng)鎖機(jī)制帶來的性能開銷問題。

鎖的升級: 偏向鎖->輕量級鎖->重量鎖

鎖的映射關(guān)系存在對象頭中的。32 位系統(tǒng)上各狀態(tài)如圖所示:

偏向鎖:

當(dāng) JVM 啟用了偏向鎖,那么新創(chuàng)建的對象都是可偏向狀態(tài),此時(shí) mark word 里的 thread id 為 0,表示未偏向任何線程

加鎖過程:

  1. 當(dāng)對象第一次被線程獲取鎖時(shí),發(fā)現(xiàn)是未偏向的,那就將 thread id 改為當(dāng)前線程 id,成功繼續(xù)執(zhí)行同步塊中的代碼,失敗則升級為輕量級鎖
  2. 當(dāng)被偏向的線程再次進(jìn)入同步塊時(shí),發(fā)現(xiàn)鎖偏向的就是當(dāng)前線程,通過一些額外檢查后就繼續(xù)執(zhí)行。
  3. 當(dāng)其他線程進(jìn)入同步塊,發(fā)現(xiàn)有偏向的線程了,會(huì)進(jìn)入撤銷偏向鎖邏輯。

解鎖過程:

  1. 棧中的最近一條 lock record 的 obj 字段設(shè)置為 null

輕量級鎖:

線程在執(zhí)行同步塊之前,JVM 會(huì)在線程的棧幀上建立一個(gè) Lock Record。其包括了一個(gè)存儲(chǔ)對象頭中的 mark word 的 Displaced Mark Word 以及一個(gè)對象頭指針。

加鎖過程:

  1. 在線程棧中創(chuàng)建一個(gè) Lock Record,將其 obj refercence 字段指向鎖對象。
  2. 通過 CAS 指令將 Lock Record 地址放在對象頭的 mark word 中,如果對象是無鎖狀態(tài)則修改成功,代表獲取到了輕量級鎖。如果失敗進(jìn)入步驟 3
  3. 如果線程以及持有該鎖了,代表這是鎖重入,設(shè)置 Lock Record 第一部分(Displaced Mark Word)為 null,起到了一個(gè)重入計(jì)數(shù)器的作用。然后結(jié)束
  4. 走到這一步說明發(fā)生了競爭,膨脹為重量鎖。

解鎖過程:

  1. 遍歷線程棧,找到所有 obj 字段等于當(dāng)前鎖對象的 Lock Record
  2. 如果 Lock Record 的 Displaced Mark Word 為 null,代表是一次重入,將 obj 設(shè)為 null 后 continue
  3. 如果 Lock Record 的 Displaced Mark Word 不為 null,則利用 CAS 指令將對象頭的 mark word 恢復(fù)成為 Displaced Mark Word。如果成功,則 continue,否則膨脹為重量級鎖

重量級鎖:

利用的是 JVM 的監(jiān)視器(Monitor)

java 會(huì)為每個(gè) object 對象分配一個(gè) monitor,當(dāng)某個(gè)對象的同步方法(synchronized methods )被多個(gè)線程調(diào)用時(shí),該對象的 monitor 將負(fù)責(zé)處理這些訪問的并發(fā)獨(dú)占要求。

  1. 當(dāng) Sychronized 修飾在代碼塊上的時(shí)候,使用的是 monitorenter 指令和 monitorexit 指令。

monitorenter

過程如下:

  • 如果 Monitor 的進(jìn)入數(shù)為 0,則該線程進(jìn)入 Monitor,然后進(jìn)入數(shù)+1,然后該線程即為 Monitor 的所有者
  • 如果線程已經(jīng)占有了 Monitor 只是重新進(jìn)入,則進(jìn)入數(shù)+1
  • 如果其他線程占有了,則線程阻塞,直到 Monitor 的進(jìn)入數(shù)為 0,在嘗試獲取

monitorexit

過程如下:

  • 指令執(zhí)行時(shí),Monitor 的進(jìn)入數(shù)減一,如果進(jìn)入數(shù)為 0,則線程退出 Monitor
  • 其他被阻塞的線程可以嘗試獲取這個(gè) Monitor 的所有權(quán)
  1. Synchronize 作用在方式里時(shí),會(huì)加上一個(gè) ACC_SYNCHRONIZED 標(biāo)識。當(dāng)有這個(gè)標(biāo)識后,線程執(zhí)行將先獲取 Monitor,獲取成功才能執(zhí)行方法體。

三、AQS

// acquire方法獲取資源占有權(quán)
public final void acquire(int arg) {
/** 嘗試獲取,tryAcquire方法是子類必須實(shí)現(xiàn)的方法,
* 比如公平鎖和非公平鎖的不同就在于tryAcquire方法的實(shí)現(xiàn)的不同。
* 獲取失敗,則addWaiter方法,包裝node節(jié)點(diǎn),放入node雙向鏈表。再acquireQueued堵塞線程,循環(huán)獲取資源占有權(quán)。
*/
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
private Node addWaiter(Node mode) {
//新構(gòu)建的node節(jié)點(diǎn),waitStatus初始值為0
Node node = new Node(Thread.currentThread(), mode);
//Try the fast path of enq; backup to full enq on failure
Node pred = tail;
//如果尾部不為空,則說明node雙向鏈表之前已經(jīng)被初始化了,那么直接把新node節(jié)點(diǎn)加入尾部
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
//如果尾部為null,則說明node雙向鏈表之前沒有被初始化,則,調(diào)用enq方法,初始化node雙向鏈表,并且把新節(jié)點(diǎn)加入尾部
enq(node);
return node;
}

acquire 方法總結(jié):

如果獲取成功:則 state 加 1,并調(diào)用 AQS 的父類
AbstractOwnableSynchronizer 的設(shè)置獨(dú)占線程,把當(dāng)前獨(dú)占線程設(shè)置當(dāng)前線程。
如果調(diào)用失敗:則說明,前面已經(jīng)有線程占用了這個(gè)資源,需要等待的線程釋放。則把當(dāng)前線程封裝成 node 節(jié)點(diǎn),放入 node 雙向鏈表,之后 Locksupport.pack()堵塞當(dāng)前線程。假如這個(gè)線程堵塞后被喚醒,則繼續(xù)循環(huán)調(diào)用 tryAcquire 方法獲取資源許可,獲取到了,則把自身 node 節(jié)點(diǎn)設(shè)置為 node 鏈表的頭節(jié)點(diǎn),把之前的頭節(jié)點(diǎn)去掉。
node 節(jié)點(diǎn)的 waitStatus 為 signal,則意味這其 next 節(jié)點(diǎn)可以被喚醒。

release 方法總結(jié):

如果線程釋放資源,調(diào)用 release 方法,release 方法會(huì)調(diào)用 tryRelease 方法嘗試釋放資源,如果釋放成功,tryRelease 方法會(huì)將 state 減 1,再調(diào)用 AQS 的父類
AbstractOwnableSynchronizer 的設(shè)置獨(dú)占線程為 null,再 locksupport.unpack()雙向 node 鏈表的頭 node 節(jié)點(diǎn)的線程,恢復(fù)其執(zhí)行。

四、實(shí)戰(zhàn)

順序打印 ABC。

/**
* @description:
* @author: mmc
* @create: 2020-01-03 09:42
**/
public class ThreadABC {
private static Object A = new Object();
private static Object B = new Object();
private static Object C = new Object();
private static class ThreadPrint extends Thread{
private String name;
private Object prev;
private Object self;
public ThreadPrint(String name,Object prev,Object self){
this.name=name;
this.prev=prev;
this.self=self;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (prev) {
synchronized (self) {
System.out.println(name);
self.notifyAll();
}
try {
if(i>=9){
prev.notifyAll();
}else {
prev.wait();
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadPrint threadA = new ThreadPrint("A",C,A);
ThreadPrint threadB = new ThreadPrint("B",A,B);
ThreadPrint threadC = new ThreadPrint("C",B,C);
threadA.start();
Thread.sleep(10);
threadB.start();
Thread.sleep(10);
threadC.start();
}
}


責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2024-07-08 00:00:01

多線程ThreadC#

2024-10-10 16:53:53

守護(hù)線程編程

2025-01-16 16:41:00

ObjectConditionJDK

2024-02-05 12:08:07

線程方式管理

2024-07-01 08:40:18

tokio派生線程

2024-05-28 09:12:10

2024-04-07 00:00:00

ESlint命令變量

2025-02-07 10:14:36

2023-04-26 10:21:04

2023-12-20 08:23:53

NIO組件非阻塞

2024-04-30 09:02:48

2023-12-12 08:41:01

2009-10-22 14:55:06

網(wǎng)絡(luò)綜合布線資料

2011-05-07 11:11:21

LCD拼接

2022-02-25 08:13:03

物聯(lián)網(wǎng)IOT

2020-09-28 11:14:57

線程數(shù)據(jù)語言

2022-12-02 14:12:52

新能源汽車海爾

2025-02-18 08:11:17

2022-11-04 14:16:05

2023-03-21 07:39:51

CentOS掛載硬盤
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 黄视频国产 | 国产精品一卡二卡三卡 | 一区二区三区四区在线 | 成人免费福利 | 国产黄色大片在线免费观看 | 亚洲欧美在线观看 | 国产成人久久 | 国产电影一区二区在线观看 | 91视频.com | 精品国产一区二区三区成人影院 | 91在线导航| 国产高清视频在线观看播放 | 国产成人久久精品 | 欧州一区 | 福利网站导航 | 涩涩视频大全 | 成人毛片网 | 激情一区二区三区 | 日韩视频一区在线观看 | 日韩av最新网址 | 日本一二区视频 | 男女午夜免费视频 | 蜜臀av日日欢夜夜爽一区 | 一级做a爰片性色毛片16美国 | 91婷婷韩国欧美一区二区 | 国产日韩一区 | 欧美一级片免费看 | 国产夜恋视频在线观看 | 国产成人久久av免费高清密臂 | 色噜噜色综合 | 99精品国产一区二区三区 | 日韩一级 | www.色五月.com | 国产精品国产精品国产专区不片 | av黄色免费| 国产一区二区三区亚洲 | 国产精品资源在线观看 | 鲁大师一区影视 | 天天爱爱网 | 国产精品99久久久久久动医院 | 国产色在线 |