java多線程---線程的同步

一叔遂、重點知識

thread重寫了tostring方法

getid()獲得線程的標(biāo)識符 從一開始,是唯一的,在生命周期中保持不變锋勺,線程死亡后此標(biāo)識符可以被重用

main的標(biāo)識符為1

通過線程標(biāo)識符变丧,可以對線程進(jìn)行區(qū)分芽狗。

sleep使當(dāng)前正在執(zhí)行的線程進(jìn)入睡眠和誰調(diào)用這個方法沒有關(guān)系

sleep是醒了之后繼續(xù)執(zhí)行,不是重新執(zhí)行一次痒蓬。

反射中創(chuàng)建運行時類時會報編譯時異常InstantiationException

守護(hù)線程(setDaemon)守護(hù)前臺線程(就是我們ide控制的線程)垃圾回收機制就是個守護(hù)進(jìn)程

前臺線程結(jié)束童擎,后臺線程就結(jié)束了

線程死亡后會被銷毀

原子性操作:代碼一次性被一個線程執(zhí)行完,不能被其他線程插入

方法要想執(zhí)行得放在椆ド梗空間中

棧是用來執(zhí)行方法的

jvm虛擬機啟動后最少存在兩個線程顾复,實際情況啟動了很多線程,但最少存在兩個鲁捏,主線程和gc垃圾回收線程

線程并不是程序開的芯砸,而是程序申請開線程,操作系統(tǒng)給程序開的線程给梅,線程的管理權(quán)和監(jiān)測權(quán)歸操作系統(tǒng)所有

一個新的線程開啟之后不會阻塞當(dāng)前代碼的執(zhí)行

多線程的優(yōu)勢

https://blog.csdn.net/stonesing/article/details/49746661

多線程的最大意義是節(jié)省等待時間假丧,在一個線程需要等待時可以執(zhí)行其他線程

如果程序中沒有等待時間,多線程將變得毫無意義

線程越多动羽,效率越低包帚,系統(tǒng)需要維護(hù),監(jiān)測管理多線程运吓,所以會降低效率渴邦,浪費性能

就緒狀態(tài)是一定存在的

自己創(chuàng)建的線程的run方法中還可以創(chuàng)建線程

新的線程是老的線程創(chuàng)建的

主線程與其他線程的關(guān)系

https://www.cnblogs.com/qiumingcheng/p/8202393.html

當(dāng)非守護(hù)線程結(jié)束后,守護(hù)線程不是立即結(jié)束拘哨,他有一個檢測過程

程序運行到什么位置會失去執(zhí)行權(quán)是不固定的

最好不要讓線程共享數(shù)據(jù)谋梭,是解決多線程安全問題得最優(yōu)解

二、重點問題

同步監(jiān)視器的選取問題

自己定義的鎖記得千萬不能定義到run方法中倦青,不然每個run方法都會創(chuàng)建一個鎖.....字面常量也可以當(dāng)鎖瓮床,內(nèi)存中只有一份

繼承實現(xiàn)線程的時候,鎖可以在外部創(chuàng)造,然后在構(gòu)造方法中傳入鎖纤垂,這樣就能保證用的是一把鎖

三矾策、課堂知識

3.1、線程的兩種啟動方式

Thread類:JDK提供好的類峭沦,用于表示一個線程對象贾虽。實現(xiàn)了Runnable接口

Runnable接口:定義了唯一的一個方法:run()——>線程體

方法一:直接繼承Thread類

step1:創(chuàng)建一個子類,來繼承Thread類

step2:重寫run()方法吼鱼,因為這是線程體:當(dāng)CPU調(diào)度執(zhí)行該線程的時候蓬豁,就要執(zhí)行的是run()方法中的代碼。

step3:創(chuàng)建該類的對象菇肃,表示一個線程地粪,調(diào)用start()進(jìn)而啟動這個線程。意味著該線程一切準(zhǔn)備就緒琐谤,隨時可以被CPU調(diào)度執(zhí)行蟆技。但是CPU并不是立即執(zhí)行,要看CPU自己是否調(diào)用了這個線程斗忌。

方法二:實現(xiàn)Runnable接口

step1:創(chuàng)建一個實現(xiàn)類质礼,實現(xiàn)Runnable接口

step2:重寫run()方法

step3:先創(chuàng)建該實現(xiàn)類對象,根據(jù)實現(xiàn)類對象再創(chuàng)建Thread對象织阳,然后啟動眶蕉。

Thread類的構(gòu)造方法:

Thread();//創(chuàng)建一個線程對象,執(zhí)行run()唧躲。線程的默認(rèn)名:Thread-0,1,2...

Thread(Runnable target);//創(chuàng)建一個線程對象造挽,指明了target,執(zhí)行的run是Runnable接口中弄痹。

Thread(String name);//創(chuàng)建一個線程饭入,并給起個名字

Thread(Runnable target,String name);

對比兩種創(chuàng)建并啟動線程的方式:

* 開發(fā)中:優(yōu)先選擇:實現(xiàn)Runnable接口的方式

* 原因:1. 實現(xiàn)的方式?jīng)]類的單繼承性的局限性

*? ? ? ? ? ? ?2. 實現(xiàn)的方式更適合來處理多個線程共享數(shù)據(jù)的情況。

* 聯(lián)系:public class Thread implements Runnable

* 相同點:兩種方式都需要重寫run(),將線程要執(zhí)行的邏輯聲明在run()中界酒。

? ? ? ? ? ? ? ? ?目前兩種方式圣拄,要想啟動線程嘴秸,都是調(diào)用的Thread類中的start()毁欣。

3.2、線程的常用方法

關(guān)于Thread類的常用方法:

1岳掐、獲取當(dāng)前的線程對象:由Thread類直接調(diào)用凭疮,獲取當(dāng)前正在被執(zhí)行的那個線程

static Thread currentThread() ;//返回對當(dāng)前正在執(zhí)行的線程對象的引用。?

2串述、線程的名字:當(dāng)一個線程創(chuàng)建的時候执解,如果沒有設(shè)置名稱:構(gòu)造方法設(shè)置,或者setName()設(shè)置。系統(tǒng)默認(rèn)的:Thread-0,Thread-1,Thread-2......

String getName()

返回此線程的名稱衰腌。

void setName(String name)

將此線程的名稱更改為等于參數(shù) name 新蟆。

3、線程的Id:每個線程創(chuàng)建的時候右蕊,由系統(tǒng)自動分配一個Id琼稻,long類型的數(shù)值,終身不變饶囚。從線程的出生到死亡帕翻。

? ? 該Id值,由系統(tǒng)自動分配萝风,程序員無法手動操作嘀掸。

long getId()

返回此線程的標(biāo)識符。

4规惰、線程的優(yōu)先級:priority

? ? System.out.println("最大優(yōu)先級:"+Thread.MAX_PRIORITY);//10

System.out.println("最小優(yōu)先級:"+Thread.MIN_PRIORITY);//1

System.out.println("正常優(yōu)先級:"+Thread.NORM_PRIORITY);//5

當(dāng)一個線程被創(chuàng)建的時候睬塌,由系統(tǒng)自動分配一個優(yōu)先級,固定都是正常優(yōu)先級:5

但是程序員可以根據(jù)需求歇万,手動調(diào)整線程的優(yōu)先級衫仑。

? ? int getPriority()

返回此線程的優(yōu)先級

? ? void setPriority(int newPriority)

更改此線程的優(yōu)先級。

? ? 優(yōu)先級別高堕花,被CPU調(diào)度執(zhí)行的機會就多文狱。但是不絕對。

? ? 優(yōu)先級別低缘挽,被CPU執(zhí)行的機會就少瞄崇,但是也不絕對。

5壕曼、線程的睡眠

? ? static void sleep(long millis)

使當(dāng)前正在執(zhí)行的線程以指定的毫秒數(shù)暫停(暫時停止執(zhí)行)苏研,具體取決于系統(tǒng)定時器和調(diào)度程序的精度和準(zhǔn)確性。

? ? 靜態(tài)方法腮郊,應(yīng)該由類直接調(diào)用摹蘑,對象也可以調(diào)用,有坑:不是誰調(diào)用就誰睡轧飞,而是當(dāng)前正在執(zhí)行的線程進(jìn)入睡眠了衅鹿。和誰調(diào)用無關(guān)。

6过咬、線程合并

在線程a中調(diào)用線程b的join(),此時線程a就進(jìn)入阻塞狀態(tài)大渤,直到線程b完全執(zhí)行完以后,線程a才結(jié)束阻塞狀態(tài)掸绞。

等待這個線程死亡泵三。

? t1線程,t2線程,main線程

? ? t1,t2,main--->3條線程搶占資源

? ? 某一個時刻:main線程中:t1.join()烫幕,主線程要等待t1線程死亡之后再執(zhí)行

? ? t1俺抽,t2--->2條線程搶占資源,main等

? ? t1結(jié)束后较曼,main線程再執(zhí)行

7凌埂、守護(hù)線程

? ? setDaemon();

為前臺線程服務(wù),如果所有的前臺線程都結(jié)束了诗芜,那么守護(hù)線程也就結(jié)束了瞳抓。

GC:垃圾自動回收機制。JVM啟動后伏恐,創(chuàng)建主線程執(zhí)行main()的時候孩哑。。翠桦。隨之而創(chuàng)建并啟動的還有很多后臺線程横蜒,比如gc()

3.3、線程的狀態(tài)

線程的生命周期:

線程new出來:新建

準(zhǔn)備就緒销凑,啟動:start:就緒狀態(tài)

如果被CPU調(diào)度執(zhí)行:運行狀態(tài)丛晌,run()方法

阻塞狀態(tài):-->進(jìn)入就緒

出生-->就緒-->運行-->死亡


線程的生命周期

3.4、臨界資源的安全問題

概念:多個線程訪問共享的數(shù)據(jù)斗幼,臨界資源澎蛛。多個線程之間存在共享的數(shù)據(jù)。一條線程執(zhí)行過程中蜕窿,其他線程也可以訪問谋逻,可能會修改數(shù)據(jù)的值。造成的共享數(shù)據(jù)的不安全桐经。叫做臨界資源的安全問題毁兆。

3.5、同步synchronized

同步:原子性操作阴挣。同步起來的代碼气堕,一次只能被1個線程執(zhí)行完畢,這個過程中畔咧,不能被其他的線程插入執(zhí)行茎芭。

同步的原理:

對象的"互斥鎖"。每個對象都可以看做一個鎖盒卸。有兩種狀態(tài):打開(默認(rèn))骗爆,關(guān)閉。

鎖對象:多條線程功能訪問的同一個對象蔽介。

同步的方式一:同步代碼塊

*? synchronized(同步監(jiān)視器){

*? ? ? //需要被同步的代碼

*? }

*? 說明:1.操作共享數(shù)據(jù)的代碼,即為需要被同步的代碼。? -->不能包含代碼多了虹蓄,也不能包含代碼少了犀呼。

*? ? ? ? ? ? ?2.共享數(shù)據(jù):多個線程共同操作的變量。比如:ticket就是共享數(shù)據(jù)薇组。

*? ? ? ? ? ? ?3.同步監(jiān)視器外臂,俗稱:鎖。任何一個類的對象律胀,都可以充當(dāng)鎖宋光。

*? ? ? ? ? 要求:多個線程必須要共用同一把鎖。

*

* 補充:在實現(xiàn)Runnable接口創(chuàng)建多線程的方式中炭菌,我們可以考慮使用this充當(dāng)同步監(jiān)視器罪佳。

? ? ? 在繼承Thread類創(chuàng)建多線程的方式中,慎用this充當(dāng)同步監(jiān)視器黑低,考慮使用當(dāng)前類充當(dāng)同步監(jiān)視器赘艳。

*?同步的 方式二:同步方法

*? ? 如果操作共享數(shù)據(jù)的代碼完整的聲明在一個方法中,我們不妨將此方法聲明同步的克握。

*? 關(guān)于同步方法的總結(jié):

*? 1. 同步方法仍然涉及到同步監(jiān)視器蕾管,只是不需要我們顯式的聲明。

*? 2. 非靜態(tài)的同步方法菩暗,同步監(jiān)視器是:this

*? ? 靜態(tài)的同步方法掰曾,同步監(jiān)視器是:當(dāng)前類本身

死鎖:多個線程互相持有對象,僵持的現(xiàn)象停团。

解決死鎖:

1婴梧、減少成員變量的使用。

2客蹋、加大鎖的粒度塞蹭。不要鎖小對象,鎖大對象讶坯。

注意字面常量也能充當(dāng)鎖番电,他在內(nèi)存中也是唯一的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市辆琅,隨后出現(xiàn)的幾起案子漱办,更是在濱河造成了極大的恐慌,老刑警劉巖婉烟,帶你破解...
    沈念sama閱讀 212,657評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娩井,死亡現(xiàn)場離奇詭異,居然都是意外死亡似袁,警方通過查閱死者的電腦和手機洞辣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,662評論 3 385
  • 文/潘曉璐 我一進(jìn)店門咐刨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扬霜,你說我怎么就攤上這事定鸟。” “怎么了著瓶?”我有些...
    開封第一講書人閱讀 158,143評論 0 348
  • 文/不壞的土叔 我叫張陵联予,是天一觀的道長。 經(jīng)常有香客問我材原,道長沸久,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,732評論 1 284
  • 正文 為了忘掉前任余蟹,我火速辦了婚禮卷胯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘客叉。我一直安慰自己诵竭,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,837評論 6 386
  • 文/花漫 我一把揭開白布兼搏。 她就那樣靜靜地躺著卵慰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佛呻。 梳的紋絲不亂的頭發(fā)上裳朋,一...
    開封第一講書人閱讀 50,036評論 1 291
  • 那天,我揣著相機與錄音吓著,去河邊找鬼鲤嫡。 笑死,一個胖子當(dāng)著我的面吹牛绑莺,可吹牛的內(nèi)容都是我干的暖眼。 我是一名探鬼主播,決...
    沈念sama閱讀 39,126評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼纺裁,長吁一口氣:“原來是場噩夢啊……” “哼诫肠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起欺缘,我...
    開封第一講書人閱讀 37,868評論 0 268
  • 序言:老撾萬榮一對情侶失蹤栋豫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谚殊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丧鸯,經(jīng)...
    沈念sama閱讀 44,315評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,641評論 2 327
  • 正文 我和宋清朗相戀三年嫩絮,在試婚紗的時候發(fā)現(xiàn)自己被綠了丛肢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片围肥。...
    茶點故事閱讀 38,773評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖摔踱,靈堂內(nèi)的尸體忽然破棺而出虐先,到底是詐尸還是另有隱情怨愤,我是刑警寧澤派敷,帶...
    沈念sama閱讀 34,470評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站撰洗,受9級特大地震影響篮愉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜差导,卻給世界環(huán)境...
    茶點故事閱讀 40,126評論 3 317
  • 文/蒙蒙 一试躏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧设褐,春花似錦颠蕴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,859評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至外冀,卻和暖如春寡键,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雪隧。 一陣腳步聲響...
    開封第一講書人閱讀 32,095評論 1 267
  • 我被黑心中介騙來泰國打工西轩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脑沿。 一個月前我還...
    沈念sama閱讀 46,584評論 2 362
  • 正文 我出身青樓藕畔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親庄拇。 傳聞我的和親對象是個殘疾皇子注服,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,676評論 2 351

推薦閱讀更多精彩內(nèi)容

  • Java多線程學(xué)習(xí) [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,952評論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步丛忆、線程數(shù)據(jù)傳遞祠汇、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等熄诡。 首先講...
    李欣陽閱讀 2,444評論 1 15
  • 1 多線程 1.1 多線程介紹 ??學(xué)習(xí)多線程之前可很,我們先要了解幾個關(guān)于多線程有關(guān)的概念。??進(jìn)程:進(jìn)程指正在運行...
    圣堂刺客_x閱讀 351評論 0 0
  • 林炳文Evankaka原創(chuàng)作品凰浮。轉(zhuǎn)載自http://blog.csdn.net/evankaka 本文主要講了ja...
    ccq_inori閱讀 648評論 0 4
  • 一擴展javalangThread類二實現(xiàn)javalangRunnable接口三Thread和Runnable的區(qū)...
    和帥_db6a閱讀 485評論 0 1