Java深入淺出講解多線程的概念到使用
下面開始學(xué)習(xí)Java多線程吧!
寫在前面:Java系統(tǒng)在語言層次上對(duì)多線程直接提供支持,多線程的主要目的是將一個(gè)程序中的各個(gè)程序段并發(fā)化,在在通常情況下,Java程序各部分是按順序一次執(zhí)行的,由于某種原因,需要將這些按順序執(zhí)行的程序段轉(zhuǎn)化為并發(fā)執(zhí)行,每個(gè)程序段在邏輯上是相互完整的代碼段。實(shí)際上,在單處理器上,同一時(shí)刻只能執(zhí)行一個(gè)代碼,但是在同一時(shí)間段內(nèi),這些代碼交替執(zhí)行,所謂的“微觀串行,宏觀并行”。
1.線程的幾個(gè)相關(guān)概念
多線程編程的含義就是將一個(gè)程序任務(wù)分為幾個(gè)可以同時(shí)并發(fā)執(zhí)行的子任務(wù)。
程序:程序是含有指令和數(shù)據(jù)的文件,也可以說程序是靜態(tài)代碼,被存儲(chǔ)在磁盤或者其他的數(shù)據(jù)存儲(chǔ)設(shè)備中。
進(jìn)程:進(jìn)程是程序執(zhí)行一次的過程。進(jìn)程是系統(tǒng)運(yùn)行程序的單位,因此進(jìn)程是動(dòng)態(tài)的。當(dāng)程序運(yùn)行時(shí)就會(huì)被系統(tǒng)載入內(nèi)存,并且啟動(dòng)他的工作。對(duì)于完全不相關(guān)的程序,在同時(shí)執(zhí)行時(shí),不會(huì)做數(shù)據(jù)的交換,而且可以完全獨(dú)立運(yùn)行。
多任務(wù):多任務(wù)是在一個(gè)系統(tǒng)中可以同時(shí)運(yùn)行多個(gè)進(jìn)程。每個(gè)進(jìn)程都是獨(dú)立的任務(wù),每個(gè)進(jìn)程都有自己獨(dú)立的內(nèi)存。所謂的同時(shí)運(yùn)行進(jìn)程,其實(shí)是操作系統(tǒng)將資源分配給各個(gè)進(jìn)程以后,每個(gè)進(jìn)程在CPU上交替運(yùn)行。
線程:線程是比進(jìn)程更小的執(zhí)行單位。一個(gè)進(jìn)程執(zhí)行過程可以產(chǎn)生多個(gè)線程,形成多條執(zhí)行路徑,提高了運(yùn)行效率。不同的是,同類的多個(gè)線程共享同一塊內(nèi)存,在進(jìn)行各個(gè)線程的切換時(shí)開銷比進(jìn)程小很多。
多線程:同時(shí)執(zhí)行一個(gè)以上的線程,一個(gè)線程的執(zhí)行不必等到另一個(gè)線程執(zhí)行完成在執(zhí)行。
2.線程的狀態(tài)與生命周期
每個(gè)Java程序都有一個(gè)默認(rèn)的主線程,對(duì)于應(yīng)用程序來說其主線程就是main()方法執(zhí)行的線程。要想實(shí)現(xiàn)多線程,必須在主線程中創(chuàng)建新的線程對(duì)象,Java語言使用Thread類及其子類的對(duì)象來表示線程,新線程的建立在它完整的生命周期中通常要經(jīng)歷五種狀態(tài),通過線程的控制和調(diào)度可以實(shí)現(xiàn)這幾種狀態(tài)之間的轉(zhuǎn)化。

1. 新建狀態(tài):線程對(duì)象聲明和創(chuàng)建,未被執(zhí)行之前。
2. 就緒狀態(tài):處于新建狀態(tài)的線程被啟動(dòng)后進(jìn)入線程隊(duì)列排隊(duì)等待CPU時(shí)間片。
3. 運(yùn)行狀態(tài):就緒狀態(tài)的線程被調(diào)度并獲得CPU資源。
4. 阻塞狀態(tài):在特殊情況下讓出CPU資源暫時(shí)中止自己的執(zhí)行。
5. 消亡狀態(tài):線程執(zhí)行完成或者程序停止運(yùn)行。
3.線程的優(yōu)先級(jí)與調(diào)度
在多線程系統(tǒng)中,每個(gè)線程都會(huì)被賦予一個(gè)優(yōu)先級(jí)。優(yōu)先級(jí)高的線程可以在一段時(shí)間內(nèi)獲得比優(yōu)先級(jí)低的線程更多的執(zhí)行時(shí)間。優(yōu)先級(jí)相同時(shí)先來先用。
創(chuàng)建一個(gè)新的線程的優(yōu)先級(jí)規(guī)則:
- 新建線程的優(yōu)先級(jí)繼承創(chuàng)建它的父線程的優(yōu)先級(jí),父線程是指創(chuàng)建新線程對(duì)象語句所在的線程。
- 一般情況下,主線程具有普通優(yōu)先級(jí),優(yōu)先級(jí)從低到高用1-10來表示。
4.Java中多線程的創(chuàng)建
4.1繼承Thread類創(chuàng)建線程
當(dāng)我們發(fā)現(xiàn)程序可以分頭執(zhí)行時(shí),就可以通過創(chuàng)建多線程分頭工作,在只有一個(gè)CPU的情況下,程序運(yùn)行時(shí)間并不會(huì)因?yàn)椴扇《嗑€程而減少,但是整體的感覺可能比較好。
Java語言中實(shí)現(xiàn)多線程的第一種方法,繼承java.lang包中的Thread類。Java語言中已經(jīng)定義了Thread類,該類中定義的方法可以實(shí)現(xiàn)線程的產(chǎn)生,執(zhí)行,終止與查看進(jìn)程的執(zhí)行狀態(tài)。
例:利用Thread類的子類創(chuàng)建線程。
class MyThread extends Thread{
private String who;
public MyThread(String name){
who=name;
}
public void run(){
for(int i=0;i<2;i++){
try{
sleep((int)(1000*Math.random()));
}
catch(InterruptedException e){}
System.out.println(who+"正在運(yùn)行...");
}
}
}
public class A_1{
public static void main(String[] args){
MyThread you=new MyThread("你");
MyThread she=new MyThread("她");
you.start();
she.start();
System.out.println("主方法運(yùn)行結(jié)束");
}
}
/**
主方法運(yùn)行結(jié)束
你正在運(yùn)行...
她正在運(yùn)行...
你正在運(yùn)行...
你正在運(yùn)行...
*/
語法:
class 類名 extends Thread{
類中的成員變量;
類中的成員方法;
修飾符 run(){
線程代碼;
}
}
4.2實(shí)現(xiàn)Runnable接口創(chuàng)建線程
由于Java不支持多重繼承,如果某個(gè)類已經(jīng)繼承了其它的父類,將無法通過繼承Thread類來創(chuàng)建線程。于是出現(xiàn)了Java中實(shí)現(xiàn)多線程的第二種方法,也是比較常用的一種方法,通過實(shí)現(xiàn)Runnable接口創(chuàng)建線程,這種方法可以使線程具有其它類的一些特征,極具靈活性。
例:利用Runnable接口創(chuàng)建線程。
class MyThread extends Thread{
private String who;
public MyThread(String name){
who=name;
}
public void run(){
for(int i=0;i<2;i++){
try{
sleep((int)(1000*Math.random()));
}
catch(InterruptedException e){}
System.out.println(who+"正在運(yùn)行...");
}
}
}
public class A_1{
public static void main(String[] args){
MyThread you=new MyThread("你");
MyThread she=new MyThread("她");
you.start();
she.start();
System.out.println("主方法運(yùn)行結(jié)束");
}
}
/**
主方法運(yùn)行結(jié)束
你正在運(yùn)行...
她正在運(yùn)行...
你正在運(yùn)行...
你正在運(yùn)行...
*/
Runnable是Java語言實(shí)現(xiàn)線程的接口。從本質(zhì)上說,實(shí)現(xiàn)線程的類必須實(shí)現(xiàn)該接口。其實(shí)Thread就是直接繼承Object類并且實(shí)現(xiàn)Runnable接口。
5.多線程的同步控制
當(dāng)多個(gè)線程之間共享數(shù)據(jù),若線程還是異步的方式訪問共享數(shù)據(jù),有時(shí)候是不安全和不符合邏輯的。此時(shí),當(dāng)一個(gè)線程對(duì)共享數(shù)據(jù)進(jìn)行修改時(shí),在沒有完成相關(guān)操作之前,其它線程不能打斷它。否則就會(huì)破壞數(shù)據(jù)的完整性,得到一個(gè)錯(cuò)誤的結(jié)果。這就是線程的同步。
線程的同步控制是在數(shù)據(jù)的共享基礎(chǔ)之上的,是為了解決多個(gè)線程共享數(shù)據(jù)導(dǎo)致的數(shù)據(jù)不一致問題。在同一時(shí)刻只允許一個(gè)線程處于操作中,這就是同步控制中的"線程間互斥"。
在并發(fā)程序中,對(duì)多線程共享的資源或數(shù)據(jù)稱為臨界資源,把線程中訪問臨界資源的代碼成為臨界代碼。臨界資源在一個(gè)時(shí)刻只能被一個(gè)線程訪問,而訪問臨界資源的代碼就是臨界代碼。
Java技術(shù)用對(duì)象"互斥鎖"的機(jī)制來實(shí)現(xiàn)線程間的互斥操作。
關(guān)于互斥鎖的機(jī)制下篇文章講解。
6.線程之間的通信
多線程的執(zhí)行往往需要相互之間的配合,為了更加有效的協(xié)調(diào)不同線程的工作,需要在線程間建立溝通渠道,通過線程間的對(duì)話來解決線程的同步問題,而不僅僅是依靠互斥機(jī)制。
Java.lang.Object中的wait()和notify()等方法為線程間的通信提供了有效手段。對(duì)于一個(gè)線程,若基于對(duì)象x調(diào)用wait()方法或notify()方法,該線程必須已經(jīng)獲得對(duì)象x的互斥鎖。也就是說,wait()和notify()只能在同步代碼里調(diào)用。
sleep()和wait()方法都能使線程堵塞,區(qū)別是:wait()方法在放棄CPU資源的同時(shí)交出了資源控制權(quán),而sleep()方法無法做到。
到此這篇關(guān)于Java深入淺出講解多線程的概念到使用的文章就介紹到這了,更多相關(guān)Java多線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java并發(fā)包JUC誕生及詳細(xì)內(nèi)容
這篇文章主要為大家介紹了java并發(fā)包JUC的誕生及JUC增加的內(nèi)容詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
Java8函數(shù)式編程應(yīng)用小結(jié)
Java8非常重要的就是引入了函數(shù)式編程的思想,使得這門經(jīng)典的面向?qū)ο笳Z言有了函數(shù)式的編程方式,彌補(bǔ)了很大程度上的不足,函數(shù)式思想在處理復(fù)雜問題上有著更為令人稱贊的特性,本文給大家介紹Java8函數(shù)式編程應(yīng)用小結(jié),感興趣的朋友一起看看吧2023-12-12
基于springboot實(shí)現(xiàn)整合shiro實(shí)現(xiàn)登錄認(rèn)證以及授權(quán)過程解析
這篇文章主要介紹了基于springboot實(shí)現(xiàn)整合shiro實(shí)現(xiàn)登錄認(rèn)證以及授權(quán)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
Java導(dǎo)出Execl疑難點(diǎn)處理的實(shí)現(xiàn)
這篇文章主要介紹了Java導(dǎo)出Execl疑難點(diǎn)處理的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Java SpringBoot實(shí)現(xiàn)文件上傳功能的示例代碼
這篇文章主要介紹了如何利用Java SpringBoot實(shí)現(xiàn)文件上傳功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定幫助,需要的可以參考一下2022-03-03
Java?properties?和?yml?的區(qū)別解析
properties和yml都是Spring?Boot支持的兩種配置文件,它們可以看做Spring?Boot在不同時(shí)期的兩種“產(chǎn)品”,這篇文章主要介紹了Java?properties?和?yml?的區(qū)別,需要的朋友可以參考下2023-02-02
Java?FTP協(xié)議實(shí)現(xiàn)文件下載功能
FTP(File?Transfer?Protocol)就是文件傳輸協(xié)議。通過FTP客戶端從遠(yuǎn)程FTP服務(wù)器上拷貝文件到本地計(jì)算機(jī)稱為下載,將本地計(jì)算機(jī)上的文件復(fù)制到遠(yuǎn)程FTP服務(wù)器上稱為上傳,上傳和下載是FTP最常用的兩個(gè)功能2022-11-11
java開發(fā)建造者模式驗(yàn)證實(shí)例詳解
這篇文章主要為大家介紹了java開發(fā)中建造者模式的驗(yàn)證實(shí)例詳解,文中附含詳細(xì)示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
SpringBoot+MybatisPlus+代碼生成器整合示例
這篇文章主要介紹了SpringBoot+MybatisPlus+代碼生成器整合示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03

