2017-12-27?多線程-thread

多線程-thread

Thread類和Runnable接口都在java.lang包中谱邪。

內(nèi)容:

1.多線程的基本概念

2.創(chuàng)建線程

3.實例-龜兔賽跑

4.線程之間的數(shù)據(jù)交流

5.線程調(diào)度

6.線程的基本控制(暫放橄仍,這里的實例是賣票那個例子)

7.線程同步(synchronized 標(biāo)記)

實現(xiàn)線程同步化需要使用synchronized 關(guān)鍵字

8.線程死鎖



1.多線程的概念

java 語言支持多線程技術(shù)。(multithreaded programing)

為什么要有多線程梁丘?

是在編程時,會遇到多個用戶的請求戴卜,為了更好地響應(yīng)多個用戶的請求捣域,并及時作出響應(yīng)授瘦。

(1)線程的概念

先介紹進(jìn)程和多進(jìn)程的概念,再介紹線程的概念竟宋。

1.1 什么叫做進(jìn)程?進(jìn)程是程序的一次動態(tài)的執(zhí)行過程形纺,經(jīng)歷了代碼開始到執(zhí)行完畢的一個完整過程丘侠。多進(jìn)程操作系統(tǒng)能并發(fā)運(yùn)行多個進(jìn)程。

并發(fā)運(yùn)行實際上是交叉運(yùn)行逐样。

因為計算機(jī)某個時刻只能執(zhí)行一個任務(wù)蜗字,

因此多進(jìn)程是指多個進(jìn)程交叉運(yùn)行打肝,給人的感覺好像是同時運(yùn)行的。

什么叫線程挪捕?

線程是由進(jìn)程派發(fā)的粗梭,是比進(jìn)程更小的執(zhí)行單位。

多線程是指在單個程序(或進(jìn)程)中同時運(yùn)行多個線程完成不同的工作,這些線程可以同時存在级零、同時運(yùn)行断医,形成多條執(zhí)行線程。如下圖所示奏纪。


線程與進(jìn)程也有共同點(diǎn)和不同點(diǎn)之處鉴嗤。

共同點(diǎn):實現(xiàn)并發(fā)的一個基本單位,都要系統(tǒng)進(jìn)行調(diào)度以提高運(yùn)行效率序调。

不同點(diǎn):(1)線程是比進(jìn)程更小的執(zhí)行單位醉锅;

? ? ? ? ? ? ? (2)每個進(jìn)程都有一個專門的內(nèi)存區(qū)域,而線程卻共享內(nèi)存單元发绢,線程是通過共享的內(nèi)存單元來實現(xiàn)數(shù)據(jù)交換硬耍、實時通信等操作。

(2)線程的狀態(tài)與生命周期


思考:當(dāng)線程的run()方法運(yùn)行完成边酒,線程就轉(zhuǎn)到(死亡)狀態(tài)经柴。


用程序進(jìn)行解釋線程的狀態(tài)與生命周期:

(1)主類中創(chuàng)建新線程對象,并且start().

(2)在創(chuàng)建的非主類中進(jìn)行寫方法run().

class Thread1 extends Thread{

//3.(運(yùn)行狀態(tài))? 一 一種是4.死亡狀態(tài)甚纲,一種是5.阻塞狀態(tài)(sleep(),wait(),join().)

? public void run(){

? ? ? ? 線程的任務(wù)

? }

}

public class Test1{

//主進(jìn)程 口锭,即main()方法。

? public static void main(String [] argps){

? ? ? ? Thread1 th = new Thread1(); //創(chuàng)建新線程的實例化對象介杆。1.(新建狀態(tài))

? ? ? ? th.start();//2.(就緒狀態(tài))

}

}

在一個系統(tǒng)中鹃操,任何時刻最多只有一個運(yùn)行態(tài)線程。

sleep(),yield(),wait(),join()四個方法的定義和區(qū)別春哨?

2.創(chuàng)建線程

(1)創(chuàng)建線程有兩種方式:

? ? ? 1.通過繼承Thread類創(chuàng)建線程荆隘。(喜歡用這個)

? ? ? ? 2.通過實現(xiàn)Runnable接口創(chuàng)建線程。

是否在任何情況下都能用任何一種方式創(chuàng)建線程赴背?

注:(1)Thread類和Runnable接口都在java.lang包中椰拒。

? ? ? ? ? (2)? 創(chuàng)建新線程必須有run()方法。

解釋:

Runnable接口:在這個接口中只定義了run()方法凰荚,這個方法是線程執(zhí)行的主體燃观,在線程獲取CPY時間運(yùn)行時,就是自動執(zhí)行線程的run()方法便瑟,因此缆毁,新的線程要完成的任務(wù)流程應(yīng)該寫在run()方法中,所以創(chuàng)建新線程就必須有run()方法到涂。創(chuàng)建線程時脊框,可以通過實現(xiàn)Runnable接口獲取run()方法颁督。

Thread類:這個類是已經(jīng)實現(xiàn)了Runnable接口的類,在這個類中除了擁有run()方法浇雹,還提高了對線程操作的方法沉御,因此可以通過繼承Thread類創(chuàng)建新線程。


1.通過繼承Thread類創(chuàng)建線程


Thread類格式:

pulic class Thread extends Object implements Runnable

實例:

ThreadTest.java

package Thread;

/*步驟:

(1)主類中創(chuàng)建新線程對象昭灵,并且start().

(2)在創(chuàng)建的非主類中繼承Thread類進(jìn)行寫方法run().

*/

//通過繼承Thread類創(chuàng)建新線程

class Thread1 extends Thread{

//3.那么就開始執(zhí)行run().[線程的任務(wù)寫在run()中]

public void run(){

for(int i=0;i<100;i++)

System.out.println("Thread1在運(yùn)行");

}

}

public class ThreadTest {

? public static void main(String[] args) {

Thread1 th = new Thread1(); //1.創(chuàng)建新線程對象

th.start(); //2.啟動線程Thread1

for(int i=0;i<100;i++)

System.out.println("main在運(yùn)行");//4.執(zhí)行完線程后吠裆,執(zhí)行主線程中剩余的語句。

}

}


在這里有兩條執(zhí)行線索虎锚。由于線程的執(zhí)行速度取決于CPU時間及速度硫痰,因此線程的程序在不同的機(jī)器上運(yùn)行時,線程交替占用CPU的情況可能不一樣窜护。因此運(yùn)行結(jié)果也會出現(xiàn)一些差別效斑。

2.通過實現(xiàn)Runnable接口創(chuàng)建線程

格式:

class Thread1 implements Runnable{

? ? ? ? ? public void run(){

? ? ? ? }

}

public class RunnableTest {

public static void main(String[] args) {

/*與繼承Thread類創(chuàng)建線程的區(qū)別,

就是把實現(xiàn)相關(guān)的創(chuàng)建的實例對象傳給了Thread柱徙,同時Thread又創(chuàng)建了對象缓屠。

*/

Thread2 th2 = new Thread2();

Thread t1 = new Thread(th2);

t1.start();

}

實例:

package Thread;

/*(1)通過Runnable接口創(chuàng)建線程,基本與繼承Thread類創(chuàng)建線程一致护侮,就是在主類中有區(qū)別敌完。

? *(2)與繼承Thread類創(chuàng)建線程的區(qū)別:

就是把實現(xiàn)相關(guān)的創(chuàng)建的實例對象傳給了Thread,同時Thread又創(chuàng)建了對象羊初。

? *? ? 然后利用Thread的實例化對象啟動線程滨溉。

? * */

class Thread2 implements Runnable{

public void run(){

for(int i=0;i<100;i++)

System.out.println("Thread1在運(yùn)行");

}

}

public class RunnableTest {

public static void main(String[] args) {

/*與繼承Thread類創(chuàng)建線程的區(qū)別,

就是把實現(xiàn)相關(guān)的創(chuàng)建的實例對象傳給了Thread长赞,同時Thread又創(chuàng)建了對象晦攒。

*/

Thread2 th2 = new Thread2();

Thread t1 = new Thread(th2);

t1.start();

for(int i=0;i<100;i++)

System.out.println("main在運(yùn)行");

}

}

3.實例-龜兔賽跑

4.線程之間的數(shù)據(jù)交流

同一個進(jìn)程中的幾個線程之間是可以 共享數(shù)據(jù)的。

例如:在龜兔賽跑中得哆,可以通過獎勵他們食物的方式激勵他們賽跑脯颜。

而食物就是烏龜和兔子共享的數(shù)據(jù)。

則共享數(shù)據(jù)有兩種方式:

1.通過內(nèi)類創(chuàng)建線程

2.通過構(gòu)造器傳遞參數(shù)

1.通過內(nèi)類創(chuàng)建線程

內(nèi)類的作用是可以直接訪問外類的成員變量贩据。即把共享數(shù)據(jù)定義為外類的成員變量栋操,烏龜和兔子定義為內(nèi)類,這樣就可以實現(xiàn)兩個線程之間的數(shù)據(jù)交流了饱亮。

在本例子中矾芙,inrabtort類是包含了主類,兔子類近上,烏龜類蠕啄。其中主類外面定義了food,作為外類的成員變量。

實例:

//把所有類都寫在主類里了歼跟,且成員變量定義在主類外面。????

內(nèi)類:把一個類(內(nèi)類)定義在另一個類(外類)中格遭。

inrabtort.java?

package thread;

public class inrabtort {

public int food = 10;

public static void main(String argps[]){

inrabtort tt = new inrabtort();

tt.go();

}

public void go(){

tortoise r1 = new tortoise();

rabbit r2 = new rabbit();

r1.start();

r2.start();

}

class tortoise extends Thread{

int i,f=0;

public void run(){

for(i=1;i<=10;i++){

System.out.println("烏龜跑到了"+i+"米處");

if(food>0){

food--;f++;

System.out.println("烏龜吃了第"+f+"個食物哈街,還剩food="+food);

}

}

}

}

class rabbit extends Thread{

int i,f=0;

public void run(){

for(i=1;i<=10;i++){

System.out.println("兔子跑到了"+i+"米處");

if(food>0){

food--;f++;

System.out.println("兔子吃了第"+f+"個食物,還剩food="+food);

}

}

}

}

}

2.通過構(gòu)造器傳遞參數(shù)(比較好用拒迅,不出錯)

把共享數(shù)據(jù)寫在一個單獨(dú)的類里骚秦,然后通過構(gòu)造器傳遞參數(shù)給各個線程。也可以對公用數(shù)據(jù)定義方法璧微,供各個線程使用作箍。

在本例中,把food這個共享數(shù)據(jù)單獨(dú)放在一個類里前硫,然后在兔子類和烏龜類里都定義了food fd;

然后并設(shè)置了構(gòu)造器進(jìn)行賦值胞得,然后進(jìn)行了引用。也就是說food類屹电,烏龜類阶剑,兔子類,主類這四個是并列的危号。

實例:

package thread;

import thread.inrabtort.rabbit;

import thread.inrabtort.tortoise;

class food{

public int food =10; //共同訪問的數(shù)據(jù)

}

public class structrabtort {

public static void main(String argps[]){

structrabtort? tt = new? structrabtort();

tt.go();

}

public void go(){

food f1 =new food();

tortoise1 r1 = new tortoise1(f1);

rabbit1 r2 = new rabbit1(f1);

r1.start();

r2.start();

}

}

class tortoise1 extends Thread{

int i;

int f=0;

food fd;

public tortoise1(food fd) {

this.fd = fd;

}

public void run(){

for(i=1;i<11;i++){

System.out.println("烏龜跑到了"+i+"米處");

if(fd.food>0){

fd.food--;f++;

System.out.println("烏龜吃了第"+f+"個食物牧愁,還剩food="+fd.food);

}

}

}

}

class rabbit1 extends Thread{

int i,f=0;

food fd;

public rabbit1(food fd) {

this.fd = fd;

}

public void run(){

for(i=1;i<11;i++){

System.out.println("兔子跑到了"+i+"米處");

if(fd.food>0){

fd.food--;f++;

System.out.println("兔子吃了第"+f+"個食物,還剩food="+fd.food);

}

}

}

}

5.線程調(diào)度

(1)為什么存在線程調(diào)度外莲?



(2)優(yōu)先級

默認(rèn)優(yōu)先級是5猪半,可以通過線程實例對象.setPriority(1-10之間的數(shù)字)進(jìn)行設(shè)置。

(3)sleep(),yield(),join()的介紹

? ?使用格式:Thread.sleep(1000)偷线;






7.線程同步(synchronized 標(biāo)記)

如果不會磨确,在eclipse里輸入syn+ alt +?進(jìn)行提示。

實現(xiàn)線程同步化需要使用synchronized 關(guān)鍵字淋昭。

保證任意時刻只有一個線程訪問該共享數(shù)據(jù)俐填。






8.線程死鎖





?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市翔忽,隨后出現(xiàn)的幾起案子英融,更是在濱河造成了極大的恐慌,老刑警劉巖歇式,帶你破解...
    沈念sama閱讀 223,207評論 6 521
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驶悟,死亡現(xiàn)場離奇詭異,居然都是意外死亡材失,警方通過查閱死者的電腦和手機(jī)痕鳍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,455評論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笼呆,你說我怎么就攤上這事熊响。” “怎么了诗赌?”我有些...
    開封第一講書人閱讀 170,031評論 0 366
  • 文/不壞的土叔 我叫張陵汗茄,是天一觀的道長。 經(jīng)常有香客問我铭若,道長洪碳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,334評論 1 300
  • 正文 為了忘掉前任叼屠,我火速辦了婚禮瞳腌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘镜雨。我一直安慰自己嫂侍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,322評論 6 398
  • 文/花漫 我一把揭開白布冷离。 她就那樣靜靜地躺著吵冒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪西剥。 梳的紋絲不亂的頭發(fā)上痹栖,一...
    開封第一講書人閱讀 52,895評論 1 314
  • 那天,我揣著相機(jī)與錄音瞭空,去河邊找鬼揪阿。 笑死,一個胖子當(dāng)著我的面吹牛咆畏,可吹牛的內(nèi)容都是我干的南捂。 我是一名探鬼主播,決...
    沈念sama閱讀 41,300評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼旧找,長吁一口氣:“原來是場噩夢啊……” “哼溺健!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钮蛛,我...
    開封第一講書人閱讀 40,264評論 0 277
  • 序言:老撾萬榮一對情侶失蹤鞭缭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魏颓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岭辣,經(jīng)...
    沈念sama閱讀 46,784評論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,870評論 3 343
  • 正文 我和宋清朗相戀三年甸饱,在試婚紗的時候發(fā)現(xiàn)自己被綠了沦童。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仑濒。...
    茶點(diǎn)故事閱讀 40,989評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖偷遗,靈堂內(nèi)的尸體忽然破棺而出墩瞳,到底是詐尸還是另有隱情,我是刑警寧澤鹦肿,帶...
    沈念sama閱讀 36,649評論 5 351
  • 正文 年R本政府宣布矗烛,位于F島的核電站,受9級特大地震影響箩溃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碌嘀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,331評論 3 336
  • 文/蒙蒙 一涣旨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧股冗,春花似錦霹陡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,814評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至怯疤,卻和暖如春浆洗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背集峦。 一陣腳步聲響...
    開封第一講書人閱讀 33,940評論 1 275
  • 我被黑心中介騙來泰國打工伏社, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人塔淤。 一個月前我還...
    沈念sama閱讀 49,452評論 3 379
  • 正文 我出身青樓摘昌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親高蜂。 傳聞我的和親對象是個殘疾皇子聪黎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,995評論 2 361

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

  • 本文主要講了java中多線程的使用方法、線程同步备恤、線程數(shù)據(jù)傳遞稿饰、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等烘跺。 首先講...
    李欣陽閱讀 2,459評論 1 15
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,966評論 1 18
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法湘纵,類相關(guān)的語法,內(nèi)部類的語法滤淳,繼承相關(guān)的語法梧喷,異常的語法,線程的語...
    子非魚_t_閱讀 31,669評論 18 399
  • “阿爸,阿媽铺敌、你們快過來看汇歹!” 烏力古拖著阿媽的手向前跑,阿媽含著笑任由他拉著偿凭,看著他像看一只小馬駒产弹,阿爸在后面跟...
    流星尾閱讀 573評論 0 5
  • 假如這歲月可饒人 我愿用十年換你安康 音容笑貌 哪怕是吹過你的風(fēng) 都是那么快樂 假如你少女情懷悸動時 做了另一番抉...
    魚夏生閱讀 288評論 2 3