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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

java

JavaSE入门学习50:多线程编程(一)

發(fā)布時(shí)間:2025/3/21 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaSE入门学习50:多线程编程(一) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一進(jìn)程和線程

? ? ? ??(1)進(jìn)程和線程的基本概念

? ? ? ? 進(jìn)程:程序(任務(wù))的執(zhí)行過(guò)程;持有資源(共享內(nèi)存,共享文件)和線程。

? ? ? ? 線程:是一個(gè)程序內(nèi)部的順序控制流。

? ? ? ? 我們生活中的進(jìn)程例子很多,一個(gè)進(jìn)程就相當(dāng)于一個(gè)你在電腦上啟動(dòng)的程序。比如我們打開(kāi)最常用的聊天工具

QQ,也可以打開(kāi)Java的開(kāi)發(fā)工具Eclipse等等。這些都算Window操作系統(tǒng)上的一個(gè)進(jìn)程。

? ? ? ? 對(duì)于Window操作系統(tǒng)上一個(gè)線程,還是拿QQ進(jìn)程和Eclipse進(jìn)程來(lái)舉例,QQ進(jìn)程中的文字聊天和收發(fā)文件就是

其中的兩個(gè)線程;Eclipse進(jìn)程中的源代碼文件編輯、源代碼編譯和語(yǔ)法校驗(yàn)就是其中的三個(gè)線程。

? ? ? ? 通過(guò)上面的知識(shí)可以得出:?? ? ? ? ? ? ? ? ? ??

? ? ? ? 1)一個(gè)進(jìn)程可以有多個(gè)線程;

? ? ? ? 2)線程是系統(tǒng)中最小的執(zhí)行單元;

? ? ? ? 3)同一進(jìn)程中有多個(gè)線程;

? ? ? ? 4)線程共享進(jìn)程的資源。

? ? ? ??(2)線程和進(jìn)程的區(qū)別

? ? ? ? 每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)行上下文),進(jìn)程間的切換會(huì)有較大的開(kāi)銷(xiāo)。多進(jìn)程指的是在操作系統(tǒng)中

同時(shí)運(yùn)行多個(gè)任務(wù)(程序)。

? ? ? ?線程可以看成輕量級(jí)的進(jìn)程,同一類(lèi)線程共享代碼和數(shù)據(jù)空間,每個(gè)線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(PC),線

程切換的開(kāi)銷(xiāo)小。多線程指的是在同一程序中有多個(gè)順序流相同時(shí)執(zhí)行。

? ? ? ?(3)線程交互

? ? ? ?線程間的通信包括互斥和同步。

? ? ? ?互斥:通常表現(xiàn)在多個(gè)線程競(jìng)爭(zhēng)同一資源,比如這里只有一只筆,同時(shí)有幾個(gè)人要進(jìn)行簽到,但資源(筆)唯一,

線程(人)之間就存在競(jìng)爭(zhēng)關(guān)系,并且同一時(shí)間只有一個(gè)線程(人)能夠持有這個(gè)資(筆)。

? ? ? ?同步:同步就是協(xié)同步調(diào),按預(yù)定的先后次序進(jìn)行運(yùn)行,如進(jìn)程、線程同步,可理解為進(jìn)程或線程A和B一塊配

合,A執(zhí)行到一定程度時(shí)要依靠B的某個(gè)結(jié)果,于是停下來(lái),示意B運(yùn)行;B依言執(zhí)行,再將結(jié)果給A;A再繼續(xù)操作。

? ? ? ?二Java多線程

? ? ? ?Java多線程是通過(guò)java.lang.Thread類(lèi)來(lái)實(shí)現(xiàn)的。VM啟動(dòng)時(shí)會(huì)有一個(gè)由主方法(public static void main(){})所定義

的線程。可以通過(guò)創(chuàng)建Thread類(lèi)的實(shí)例來(lái)創(chuàng)建新的線程。每個(gè)線程都是通過(guò)某個(gè)特定Thread類(lèi)的對(duì)象所對(duì)應(yīng)的方法

run()來(lái)完成其操作的,方法run()稱(chēng)為線程體。通過(guò)調(diào)用Thread類(lèi)的start()方法來(lái)啟動(dòng)一個(gè)線程。

? ? ? ?(1)Thread類(lèi)

? ? ? ?API中定義的Thread類(lèi):

? ? ? ?線程是程序中的執(zhí)行線程。Java虛擬機(jī)允許應(yīng)用程序并發(fā)地運(yùn)行多個(gè)執(zhí)行線程。 每個(gè)線程都有一個(gè)優(yōu)先級(jí),高優(yōu)

先級(jí)線程的執(zhí)行優(yōu)先于低優(yōu)先級(jí)線程。每個(gè)線程都可以或不可以標(biāo)記為一個(gè)守護(hù)程序。當(dāng)某個(gè)線程中運(yùn)行的代碼創(chuàng)建

一個(gè)新 Thread 對(duì)象時(shí),該新線程的初始優(yōu)先級(jí)被設(shè)定為創(chuàng)建線程的優(yōu)先級(jí),并且當(dāng)且僅當(dāng)創(chuàng)建線程是守護(hù)線程時(shí),

新線程才是守護(hù)程序。?

? ? ? ?當(dāng)Java虛擬機(jī)啟動(dòng)時(shí),通常都會(huì)有單個(gè)非守護(hù)線程(它通常會(huì)調(diào)用某個(gè)指定類(lèi)的 main()方法。Java虛擬機(jī)會(huì)繼續(xù)

執(zhí)行線程,直到下列任一情況出現(xiàn)時(shí)為止:?

? ? ? ? 1)調(diào)用了Runtime類(lèi)的exit()方法,并且安全管理器允許退出操作發(fā)生。?

? ? ? ? 2)非守護(hù)線程的所有線程都已停止運(yùn)行,無(wú)論是通過(guò)從對(duì)run()方法的調(diào)用中返回,還是通過(guò)拋出一個(gè)傳播到run()

方法之外的異常。?

? ? ? ?創(chuàng)建新執(zhí)行線程有兩種方法。一種方法是將類(lèi)聲明為T(mén)hread類(lèi)的子類(lèi)。該子類(lèi)應(yīng)重寫(xiě)Thread類(lèi)的run()方法。接

下來(lái)可以分配并啟動(dòng)該子類(lèi)的實(shí)例。例如,計(jì)算大于某一規(guī)定值的質(zhì)數(shù)的線程可以寫(xiě)成:

[java]?view plaincopy print?
  • class?PrimeThread?extends?Thread?{??
  • ???????long?minPrime;??
  • ???????PrimeThread(long?minPrime)?{??
  • ???????????this.minPrime?=?minPrime;??
  • ???????}??
  • ??
  • ???????public?void?run()?{??
  • ???????????//compute?primes?larger?than?minPrime??
  • ????????????.?.?.??
  • ???????}??
  • }??
  • ? ? ? ??然后,下列代碼會(huì)創(chuàng)建并啟動(dòng)一個(gè)線程:?

    [java]?view plaincopy print?
  • PrimeThread?p?=?new?PrimeThread(143);??
  • p.start();??
  • ? ? ? ? 創(chuàng)建線程的另一種方法是聲明實(shí)Runnable接口的類(lèi)。該類(lèi)然后實(shí)現(xiàn)run()方法。然后可以分配該類(lèi)的實(shí)例,在創(chuàng)

    Thread類(lèi)時(shí)作為一個(gè)參數(shù)來(lái)傳遞并啟動(dòng)。采用這種風(fēng)格的同一個(gè)例子如下所示:?

    [java]?view plaincopy print?
  • class?PrimeRun?implements?Runnable?{??
  • ?????????long?minPrime;??
  • ?????????PrimeRun(long?minPrime)?{??
  • ?????????????this.minPrime?=?minPrime;??
  • ?????????}??
  • ???
  • ?????????public?void?run()?{??
  • ?????????????//?compute?primes?larger?than?minPrime??
  • ??????????????.?.?.??
  • ?????????}??
  • }??
  • ? ? ? ? 然后,下列代碼會(huì)創(chuàng)建并啟動(dòng)一個(gè)線程:?

    [java]?view plaincopy print?
  • PrimeRun?p?=?new?PrimeRun(143);??
  • new?Thread(p).start();??
  • ? ? ? ?每個(gè)線程都有一個(gè)標(biāo)識(shí)名,多個(gè)線程可以同名。如果線程創(chuàng)建時(shí)沒(méi)有指定標(biāo)識(shí)名,就會(huì)為其生成一個(gè)新名稱(chēng)。?

    ? ? ? ?Thread類(lèi)中定義關(guān)于線程優(yōu)先級(jí)的字段:


    ? ? ? ?Thread類(lèi)中定義的構(gòu)造方法:


    ? ? ? ?Thread類(lèi)中定義的方法:






    ? ? ? ?(2)Runnable接口

    ? ? ? ?API中描述的Runnable接口:

    ? ? ? ?Runnable接口應(yīng)該由那些打算通過(guò)某一線程執(zhí)行其實(shí)例的類(lèi)來(lái)實(shí)現(xiàn)。類(lèi)必須定義一個(gè)稱(chēng)為run()的無(wú)參數(shù)方法。

    ?設(shè)計(jì)Runnable接口的目的是為希望在活動(dòng)時(shí)執(zhí)行代碼的對(duì)象提供一個(gè)公共協(xié)議。例如,Thread類(lèi)實(shí)現(xiàn)了Runnable接

    口。激活的意思是說(shuō)某個(gè)線程已啟動(dòng)并且尚未停止。?

    ? ? ? ?此外,Runnable接口為非Thread子類(lèi)的類(lèi)提供了一種激活方式。通過(guò)實(shí)例化某個(gè) Thread類(lèi)實(shí)例并將自身作為運(yùn)

    行目標(biāo),就可以運(yùn)行實(shí)現(xiàn)Runnable接口的類(lèi)而無(wú)需創(chuàng)建Thread類(lèi)的子類(lèi)。大多數(shù)情況下,如果只想重寫(xiě)run()方法,

    而不重寫(xiě)其他Thread類(lèi)方法,那么應(yīng)使用Runnable接口。這很重要,因?yàn)槌浅绦騿T打算修改或增強(qiáng)類(lèi)的基本行

    為,否則不應(yīng)為該類(lèi)創(chuàng)建子類(lèi)。

    ? ? ? ?Runnable接口中只定義了一個(gè)方法:

    ?

    ? ? ? ?(3)線程的創(chuàng)建與啟動(dòng)

    ? ? ? ?Java中可以有兩種方式創(chuàng)建新的線程。

    ? ? ? ?第一種:定義線程類(lèi)實(shí)現(xiàn)Runnable接口

    ? ? ? ?Thread myThread=new Thread(target) ?//target為Runnable接口類(lèi)型。

    ? ? ? ?Runnable接口中只有一個(gè)方法:

    ? ? ? ?public void run();//定義線程運(yùn)行體。

    ? ? ? ?使用Runnable接口可以為多個(gè)線程提供共享的數(shù)據(jù)。

    ? ? ? ?在實(shí)現(xiàn)Runnable接口的類(lèi)的run()方法中可以使用Thread的靜態(tài)方法:

    ? ? ? ?public static Thread correntThread() ?獲取當(dāng)前線程的引用

    ? ? ? ?第二種:定義線程類(lèi)繼承Thread類(lèi)

    ? ? ? ?定義一個(gè)Thread類(lèi)的子類(lèi)并重寫(xiě)其run()方法如:

    ? ? ? ?class MyThread extends Thread{

    ? ? ? ? ? ? ? public void run(){...}

    ? ? ? ? }

    ? ? ? ? 然后生成該類(lèi)的對(duì)象:

    ? ? ? ? MyThread myThread = new Mythread(...)

    ? ? ? ? 實(shí)例:

    ? ? ? ? TestThread1.java源代碼:

    ? ? ? ? 方法調(diào)用的順序執(zhí)行,也就是先執(zhí)行Runnable1線程,再執(zhí)行主線程。

    [java]?view plaincopy print?
  • public?class?TestThread1?{??
  • ????public?static?void?main(String?args[])?{??
  • ????????<span?style="color:#ff6600;">Runner1?r?=?new?Runner1();??
  • ????????r.run();</span>??
  • ??????????
  • ????????for(int?i=0;?i<10;?i++)?{??
  • ????????????System.out.println("主線程:------"?+?i);??
  • ????????}??
  • ????}??
  • }??
  • ??
  • class?Runner1?implements?Runnable?{??
  • ????public?void?run()?{??
  • ????????for(int?i=0;?i<10;?i++)?{??????
  • ????????????System.out.println("Runner1線程:"?+?i);??
  • ????????}??
  • ????}??
  • }??
  • ? ? ? ? ?運(yùn)行結(jié)果:


    ? ? ? ? 線程啟動(dòng)后的交替執(zhí)行,其中最重要的是Thread類(lèi)的start()方法,即Runnable1線程和主線程交替執(zhí)行。

    [java]?view plaincopy print?
  • public?class?TestThread1?{??
  • ????public?static?void?main(String?args[])?{??
  • ????????<span?style="color:#ff6600;">Runner1?r?=?new?Runner1();??
  • ????????Thread?t?=?new?Thread(r);??
  • ????????t.start();</span>??
  • ??????????
  • ????????for(int?i=0;?i<10;?i++)?{??
  • ????????????System.out.println("主線程:------"?+?i);??
  • ????????}??
  • ????}??
  • }??
  • ??
  • class?Runner1?implements?Runnable?{??
  • ????public?void?run()?{??
  • ????????for(int?i=0;?i<10;?i++)?{??????
  • ????????????System.out.println("Runner1線程:"?+?i);??
  • ????????}??
  • ????}??
  • }??
  • ? ? ? ? 運(yùn)行結(jié)果:


    ? ? ? ? 使用繼承Thread類(lèi)的修改后的代碼:

    [java]?view plaincopy print?
  • public?class?TestThread1?{??
  • ????public?static?void?main(String?args[])?{??
  • ????????<span?style="color:#ff6600;">Runner1?r?=?new?Runner1();??
  • ????????r.start();</span>??
  • ??????????
  • ????????for(int?i=0;?i<10;?i++)?{??
  • ????????????System.out.println("主線程:------"?+?i);??
  • ????????}??
  • ????}??
  • }??
  • ??
  • ??
  • <span?style="color:#ff6600;">class?Runner1?extends?Thread</span>?{??
  • ????public?void?run()?{??
  • ????????for(int?i=0;?i<10;?i++)?{??????
  • ????????????System.out.println("Runner1線程:"?+?i);??
  • ????????}??
  • ????}??
  • }??
  • ? ? ? ? 運(yùn)行結(jié)果:


    ? ? ? ?推薦使用實(shí)現(xiàn)Runnable接口的線程類(lèi)來(lái)進(jìn)行多線程的創(chuàng)建與啟動(dòng),比較靈活。

    ? ? ? ?關(guān)于兩種方法創(chuàng)建線程的不同

    ? ? ? ?第一:創(chuàng)建線程只有繼承Thread類(lèi)和實(shí)現(xiàn)Runnable接口兩種方式(Thread也是實(shí)現(xiàn)了Runnable接口);

    ? ? ? ?第二:若以繼承Thread類(lèi)方式創(chuàng)建線程則這個(gè)類(lèi)的實(shí)例就可以重寫(xiě)Thread類(lèi)的幾十個(gè)方法,注意是好幾十個(gè)方

    法;
    ? ? ? ?第三:若以實(shí)現(xiàn)Runnable接口的方式創(chuàng)建線程則僅僅只有一個(gè)run()方法可供重寫(xiě)(注意是只有一個(gè));

    ? ? ? ?實(shí)現(xiàn)Runnable接口創(chuàng)建的線程最終還是要通過(guò)將自身實(shí)例作為參數(shù)傳遞給Thread類(lèi)然后執(zhí)行,當(dāng)你要為一個(gè)沒(méi)

    有繼承Thread類(lèi)的類(lèi)創(chuàng)建線程,而且只想讓這個(gè)類(lèi)的實(shí)例調(diào)用run()方法執(zhí)行任務(wù),這時(shí)候Runnable接口就相當(dāng)于為

    你的目標(biāo)類(lèi)提供了一個(gè)激活方式,設(shè)計(jì)該接口的目的是為了那些希望在激活時(shí)執(zhí)行代碼的對(duì)象提供一個(gè)公共協(xié)議,激

    活的意思是說(shuō)某個(gè)線程已啟動(dòng)并且尚未停止。?

    ? ? ? ?這兩種創(chuàng)建線程的方法本身沒(méi)有什么不同,一個(gè)是實(shí)現(xiàn)Runnable接口,一個(gè)是繼承Thread類(lèi)。而使用實(shí)現(xiàn)

    Runnable接口這種方法:1.可以避免Java的單繼承的特性帶來(lái)的局限性;2.適合多個(gè)相同程序的代碼去處理同一個(gè)資

    源的情況,把線程同程序的代碼及數(shù)據(jù)有效分離,較好地體現(xiàn)了面向?qū)ο蟮脑O(shè)計(jì)思想。開(kāi)發(fā)中大多情況下都使用實(shí)現(xiàn)

    Runnable接口這種方法創(chuàng)建線程。


    from:?http://blog.csdn.net/erlian1992/article/details/51706914

    《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專(zhuān)家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的JavaSE入门学习50:多线程编程(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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