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

歡迎訪問 生活随笔!

生活随笔

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

java

Java程序员从笨鸟到菜鸟之(十一)多线程讲解

發(fā)布時間:2025/3/21 java 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java程序员从笨鸟到菜鸟之(十一)多线程讲解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多線程是Java應(yīng)用程序的一個特點,掌握java的多線程也是作為一java程序員必備的知識。多線程指的是在單個程序中可以同時運行多個同的線程執(zhí)行不同的任務(wù).線程是程序內(nèi)的順序控制流,只能使用分配給序的資源和環(huán)境。還記得剛開始學(xué)習(xí)的時候總是和進(jìn)程分不清,總是對這兩個名詞所迷惑。

下面就首先對這兩個名詞區(qū)分來作為本篇博客的開始:

????一、線程與進(jìn)程的區(qū)別

多個進(jìn)程的內(nèi)部數(shù)據(jù)和狀態(tài)都是完全獨立的,而多線程是共享一塊內(nèi)存空間和一組系統(tǒng)資源,有可能互相影響.??線程本身的數(shù)據(jù)通常只有寄存器數(shù)據(jù),以及一個程序執(zhí)行時使用的堆棧,所以線程的切換比進(jìn)程切換的負(fù)擔(dān)要小。

?多線程編程的目的,就是"最大限度地利用CPU資源",當(dāng)某一線程的處理不需要占用CPU而只和I/O等資源打交道時,讓需要占用CPU資源的其它線程有機會獲得CPU資源。從根本上說,這就是多線程編程的最終目的。

二、了解一下java在多線程中的基礎(chǔ)知識

1.Java中如果我們自己沒有產(chǎn)生線程,那么系統(tǒng)就會給我們產(chǎn)生一個線程(主線程,main方法就在主線程上運行),我們的程序都是由線程來執(zhí)行的。

?2.?進(jìn)程:執(zhí)行中的程序(程序是靜態(tài)的概念,進(jìn)程是動態(tài)的概念)。?

3.?線程的實現(xiàn)有兩種方式,第一種方式是繼承Thread類,然后重寫run方法;第二種是實現(xiàn)Runnable接口,然后實現(xiàn)其run方法。?

4.?將我們希望線程執(zhí)行的代碼放到run方法中,然后通過start方法來啟動線程,start方法首先為線程的執(zhí)行準(zhǔn)備好系統(tǒng)資源,然后再去調(diào)用run方法。當(dāng)某個類繼承了Thread類之后,該類就叫做一個線程類。?

5.?一個進(jìn)程至少要包含一個線程。?

6.?對于單核CPU來說,某一時刻只能有一個線程在執(zhí)行(微觀串行),從宏觀角度來看,多個線程在同時執(zhí)行(宏觀并行)。?

7.?對于雙核或雙核以上的CPU來說,可以真正做到微觀并行。

三、Thread源碼研究:?

1)?Thread類也實現(xiàn)了Runnable接口,因此實現(xiàn)了Runnable接口中的run方法;?

2)?當(dāng)生成一個線程對象時,如果沒有為其設(shè)定名字,那么線程對象的名字將使用如下形式:Thread-number,該number將是自動增加的,并被所有的Thread對象所共享(因為它是static的成員變量)。?

3)?當(dāng)使用第一種方式來生成線程對象時,我們需要重寫run方法,因為Thread類的run方法此時什么事情也不做。

4)當(dāng)使用第二種方式生成線程對象時,我們需要實現(xiàn)Runnable接口的run方法,然后使用new?Thread(new?MyThread())(假如MyThread已經(jīng)實現(xiàn)了Runnable接口)來生成線程對象,這時的線程對象的run方法或調(diào)就會MyThread類的run方法,這樣我們自己編寫的run方法就執(zhí)行了。

說明:?

Public?void?run(){

If(target!=null){

Target.run();

}}

?

當(dāng)使用繼承Thread生成線程對象時,target為空,什么也不執(zhí)行,當(dāng)使用第二種方式生成時,執(zhí)行target.run(),target為runnable的實例對象,即為執(zhí)行重寫后的方法

總結(jié):兩種生成線程對象的區(qū)別:

1.兩種方法均需執(zhí)行線程的start方法為線程分配必須的系統(tǒng)資源、調(diào)度線程運行并執(zhí)行線程的run方法。?

2.在具體應(yīng)用中,采用哪種方法來構(gòu)造線程體要視情況而定。通常,當(dāng)一個線程已繼承了另一個類時,就應(yīng)該用第二種方法來構(gòu)造,即實現(xiàn)Runnable接口。?

四:線程的生命周期:

由上圖可以看出,一個線程由出生到死亡分為五個階段:

1).創(chuàng)建狀態(tài)?

?當(dāng)用new操作符創(chuàng)建一個新的線程對象時,該線程處于創(chuàng)建狀態(tài)。?

?處于創(chuàng)建狀態(tài)的線程只是一個空的線程對象,系統(tǒng)不為它分配資源?

2).?可運行狀態(tài)?

?執(zhí)行線程的start()方法將為線程分配必須的系統(tǒng)資源,安排其運行,并調(diào)用線程體—run()方法,這樣就使得該線程處于可運行(?Runnable?)狀態(tài)。?

?這一狀態(tài)并不是運行中狀態(tài)(Running?),因為線程也許實際上并未真正運行。?

3).不可運行狀態(tài)?

.當(dāng)發(fā)生下列事件時,處于運行狀態(tài)的線程會轉(zhuǎn)入到不可運行狀態(tài)。?

調(diào)用了sleep()方法;?

?線程調(diào)用wait方法等待特定條件的滿足?

?線程輸入/輸出阻塞?

4返回可運行狀態(tài):?

?處于睡眠狀態(tài)的線程在指定的時間過去后?

?如果線程在等待某一條件,另一個對象必須通過notify()notifyAll()方法通知等待線程條件的改變?

?如果線程是因為輸入/輸出阻塞,等待輸入/輸出完成?

5.?消亡狀態(tài)?

當(dāng)線程的run方法執(zhí)行結(jié)束后,該線程自然消亡。?

注意:

1.停止線程的方式:不能使用Thread類的stop方法來終止線程的執(zhí)行。一般要設(shè)定一個變量,在run方法中是一個循環(huán),循環(huán)每次檢查該變量,如果滿足條件則繼續(xù)執(zhí)行,否則跳出循環(huán),線程結(jié)束。?

2.不能依靠線程的優(yōu)先級來決定線程的執(zhí)行順序。?

五:多線程并發(fā)

多線程并發(fā)是線程同步中比較常見的現(xiàn)象,java多線程為了避免多線程并發(fā)解決多線程共享數(shù)據(jù)同步問題提供了synchronized關(guān)鍵字

synchronized關(guān)鍵字:當(dāng)synchronized關(guān)鍵字修飾一個方法的時候,該方法叫做同步方法。?

1.Java中的每個對象都有一個鎖(lock)或者叫做監(jiān)視器(monitor),當(dāng)訪問某個對象的synchronized方法時,表示將該對象上鎖,此時其他任何線程都無法再去訪問該synchronized方法了,直到之前的那個線程執(zhí)行方法完畢后(或者是拋出了異常),那么將該對象的鎖釋放掉,其他線程才有可能再去訪問該synchronized方法。?

2.?如果一個對象有多個synchronized方法,某一時刻某個線程已經(jīng)進(jìn)入到了某個synchronized方法,那么在該方法沒有執(zhí)行完畢前,其他線程是無法訪問該對象的任何synchronized方法的。?

?

3.如果某個synchronized方法是static的,那么當(dāng)線程訪問該方法時,它鎖的并不是synchronized方法所在的對象,而是synchronized方法所在的對象所對應(yīng)的Class對象因為Java中無論一個類有多少個對象,這些對象會對應(yīng)唯一一個Class對象,因此當(dāng)線程分別訪問同一個類的兩個對象的兩個static,synchronized方法時,他們的執(zhí)行順序也是順序的,也就是說一個線程先去執(zhí)行方法,執(zhí)行完畢后另一個線程才開始執(zhí)行。?

4.?synchronized塊,寫法:?

synchronized(object)?

{?

}?

表示線程在執(zhí)行的時候會對object對象上鎖。?

5.synchronized方法是一種粗粒度的并發(fā)控制,某一時刻,只能有一個線程執(zhí)行該synchronized方法;synchronized塊則是一種細(xì)粒度的并發(fā)控制,只會將塊中的代碼同步,位于方法內(nèi)、synchronized塊之外的代碼是可以被多個線程同時訪問到的。?

同步的線程狀態(tài)圖:

六:wait與notify

1.wait與notify方法都是定義在Object類中,而且是final的,因此會被所有的Java類所繼承并且無法重寫。這兩個方法要求在調(diào)用時線程應(yīng)該已經(jīng)獲得了對象的鎖,因此對這兩個方法的調(diào)用需要放在synchronized方法或塊當(dāng)中。當(dāng)線程執(zhí)行了wait方法時,它會釋放掉對象的鎖。?

2.?另一個會導(dǎo)致線程暫停的方法就是Thread類的sleep方法,它會導(dǎo)致線程睡眠指定的毫秒數(shù),但線程在睡眠的過程中是不會釋放掉對象的鎖的。?

3.notify():喚醒在此對象監(jiān)視器上等待的單個線程。如果所有線程都在此對象上等待,則會選擇喚醒其中一個線程。選擇是任意性的,并在對實現(xiàn)做出決定時發(fā)生。線程通過調(diào)用其中一個?wait?方法,在對象的監(jiān)視器上等待。?

直到當(dāng)前線程放棄此對象上的鎖定,才能繼續(xù)執(zhí)行被喚醒的線程。被喚醒的線程將以常規(guī)方式與在該對象上主動同步的其他所有線程進(jìn)行競爭;例如,喚醒的線程在作為鎖定此對象的下一個線程方面沒有可靠的特權(quán)或劣勢。

此方法只應(yīng)由作為此對象監(jiān)視器的所有者的線程來調(diào)用。通過以下三種方法之一,線程可以成為此對象監(jiān)視器的所有者:

o?通過執(zhí)行此對象的同步實例方法。

o?通過執(zhí)行在此對象上進(jìn)行同步的?synchronized?語句的正文。

o?對于?Class?類型的對象,可以通過執(zhí)行該類的同步靜態(tài)方法。

一次只能有一個線程擁有對象的監(jiān)視器。

?關(guān)于成員變量與局部變量:如果一個變量是成員變量,那么多個線程對同一個對象的成員變量進(jìn)行操作時,他們對該成員變量是彼此影響的(也就是說一個線程對成員變量的改變會影響到另一個線程)。??如果一個變量是局部變量,那么每個線程都會有一個該局部變量的拷貝,一個線程對該局部變量的改變不會影響到其他的線程。

七:死鎖的問題:?

定義:線程1鎖住了對象A的監(jiān)視器,等待對象B的監(jiān)視器,線程2鎖住了對象B的監(jiān)視器,等待對象A的監(jiān)視器,就造成了死鎖。

?????導(dǎo)致死鎖的根源在于不適當(dāng)?shù)剡\用“synchronized”關(guān)鍵詞來管理線程對特定對象的訪問。“synchronized”關(guān)鍵詞的作用是,確保在某個時刻只有一個線程被允許執(zhí)行特定的代碼塊,因此,被允許執(zhí)行的線程首先必須擁有對變量或?qū)ο蟮呐潘栽L問權(quán)。當(dāng)線程訪問對象時,線程會給對象加鎖

Java中每個對象都有一把鎖與之對應(yīng)。但Java不提供單獨的lockunlock操作。下面筆者分析死鎖的兩個過程上鎖鎖死”?

(1)?上鎖
?????許多線程在執(zhí)行中必須考慮與其他線程之間共享數(shù)據(jù)或協(xié)調(diào)執(zhí)行狀態(tài),就需要同步機制。因此大多數(shù)應(yīng)用程序要求線程互相通信來同步它們的動作,在?Java?程序中最簡單實現(xiàn)同步的方法就是上鎖。在?Java?編程中,所有的對象都有鎖。線程可以使用?synchronized?關(guān)鍵字來獲得鎖。在任一時刻對于給定的類的實例,方法或同步的代碼塊只能被一個線程執(zhí)行。這是因為代碼在執(zhí)行之前要求獲得對象的鎖。

????為了防止同時訪問共享資源,線程在使用資源的前后可以給該資源上鎖和開鎖。給共享變量上鎖就使得?Java?線程能夠快速方便地通信和同步。某個線程若給一個對象上了鎖,就可以知道沒有其他線程能夠訪問該對象。即使在搶占式模型中,其他線程也不能夠訪問此對象,直到上鎖的線程被喚醒、完成工作并開鎖。那些試圖訪問一個上鎖對象的線程通常會進(jìn)入睡眠狀態(tài),直到上鎖的線程開鎖。一旦鎖被打開,這些睡眠進(jìn)程就會被喚醒并移到準(zhǔn)備就緒隊列中。

(2)鎖死
?????如果程序中有幾個競爭資源的并發(fā)線程,那么保證均衡是很重要的。系統(tǒng)均衡是指每個線程在執(zhí)行過程中都能充分訪問有限的資源,系統(tǒng)中沒有餓死和死鎖的線程。當(dāng)多個并發(fā)的線程分別試圖同時占有兩個鎖時,會出現(xiàn)加鎖沖突的情形。如果一個線程占有了另一個線程必需的鎖,互相等待時被阻塞就有可能出現(xiàn)死鎖。

????在編寫多線程代碼時,筆者認(rèn)為死鎖是最難處理的問題之一。因為死鎖可能在最意想不到的地方發(fā)生,所以查找和修正它既費時又費力。例如,常見的例子如下面這段程序。print?

1?public?int?sumArrays(int[]?a1,?int[]?a2){??

2???int?value?=?0;??

3???int?size?=?a1.length;??

4???if?(size?==?a2.length)?{??

5??????synchronized(a1)?{?//1????????

6????????synchronized(a2)?{?//2??????????

7??????????for?(int?i=0;?i<size;?i++)??

8?????????????value?+=?a1[i]?+?a2[i];??

9????????}????

10??????}????

11???}?return?value;??

12?}???

這段代碼在求和操作中訪問兩個數(shù)組對象之前鎖定了這兩個數(shù)組對象。它形式簡短,編寫也適合所要執(zhí)行的任務(wù);但不幸的是,它有一個潛在的問題。這個問題就是它埋下了死鎖的種子。

ThreadLocal類(這個類本人沒用過,占時不太懂)

首先,ThreadLocal?不是用來解決共享對象的多線程訪問問題的,一般情況下,通過ThreadLocal.set()?到線程中的對象是該線程自己使用的對象,其他線程是不需要訪問的,也訪問不到的。各個線程中訪問的是不同的對象。

另外,說ThreadLocal使得各線程能夠保持各自獨立的一個對象,并不是通過ThreadLocal.set()來實現(xiàn)的,而是通過每個線程中的new?對象?的操作來創(chuàng)建的對象,每個線程創(chuàng)建一個,不是什么對象的拷貝或副本。通過ThreadLocal.set()將這個新創(chuàng)建的對象的引用保存到各線程的自己的一個map中,每個線程都有這樣一個map,執(zhí)行ThreadLocal.get()時,各線程從自己的map中取出放進(jìn)去的對象,因此取出來的是各自自己線程中的對象,ThreadLocal實例是作為mapkey來使用的。

如果ThreadLocal.set()進(jìn)去的東西本來就是多個線程共享的同一個對象,那么多個線程的ThreadLocal.get()取得的還是這個共享對象本身,還是有并發(fā)訪問問題。

?本文來自:曹勝歡博客專欄。轉(zhuǎn)載請注明出處:http://blog.csdn.Net/csh624366188

總結(jié)

以上是生活随笔為你收集整理的Java程序员从笨鸟到菜鸟之(十一)多线程讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 国产男女猛烈无遮挡免费视频动漫 | 一区二区高清视频 | 色偷偷888欧美精品久久久 | 亚洲欧美婷婷 | 亚洲视频一区二区三区 | 依人成人 | 精品三级视频 | 337p粉嫩色噜噜噜大肥臀 | 日免费视频 | 手机看片欧美 | 97桃色 | 免费观看成年人视频 | 国产69精品久久久久999小说 | 中文在线视频观看 | 国产成人亚洲精品无码h在线 | 一区二区三区激情视频 | 污污的视频网站在线观看 | 最近中文字幕在线mv视频在线 | www.亚洲一区| 国产麻豆一精品一男同 | 久久99久 | 精品综合在线 | 免费高清欧美大片在线观看 | 丰满少妇高潮在线观看 | 日韩av成人在线观看 | 日韩成人高清视频在线观看 | 天天爽天天爽夜夜爽毛片 | 强行糟蹋人妻hd中文字幕 | 可以免费看毛片的网站 | 精品动漫一区二区 | 久久老女人 | 99色国产| 91n视频| 白丝一区| 在线观看av黄色 | 伦理片一区二区 | 一区二区三区在线视频免费观看 | 日本精品一二三区 | 亚洲成人av电影在线 | 欧美色88| 蜜臀av性久久久久蜜臀aⅴ流畅 | 久久久久成人精品免费播放动漫 | av在线电影院 | 乌克兰少妇性做爰 | 国产精品麻豆视频 | 国产高清视频在线观看 | 97精品熟女少妇一区二区三区 | 四虎精品| 日日爽夜夜爽 | 精品不卡一区二区三区 | 九九精品视频免费 | 人妻无码久久一区二区三区免费 | 日韩欧美福利视频 | 国产另类精品 | 日韩在线视频免费 | 欧美野外猛男的大粗鳮 | 精品69| 97人人精品 | 亚洲午夜精品一区二区 | 国产综合视频一区二区 | 欧美永久视频 | 国产免费福利 | 久久精品国产亚洲av蜜臀色欲 | 日本午夜免费福利视频 | 另类三区 | 亚洲成a人v欧美综合天堂麻豆 | 国产精品一线天粉嫩av | 免费看黄色漫画 | 国产成人无码www免费视频播放 | 天堂在线资源库 | 国产精品99久久 | 张津瑜国内精品www在线 | 97潮色| 九热在线视频 | 欧美日韩亚洲色图 | 污视频免费在线观看网站 | 天天狠天天干 | 初尝人妻少妇中文字幕 | 免费观看黄色一级视频 | 91久久国产综合久久91精品网站 | 捆绑少妇玩各种sm调教 | 日韩jizz | 国产天堂在线 | 男人透女人免费视频 | 午夜影院在线免费观看 | av的天堂 | 亚洲快播 | 91高跟黑色丝袜呻吟在线观看 | 精品国产69 | 1024手机在线看片 | 天堂资源中文在线 | 中文字幕1页 | 久久爱综合 | 国产露脸国语对白在线 | 日本精品久久久久中文字幕 | 久久99久久99精品 | 国产午夜不卡 | 羞羞动漫免费观看 | 国产精品99久久久久久人 |