(Java多线程)多线程原理和使用
文章目錄
- 并發(fā)與并行
- 線程與進程
- 創(chuàng)建線程類
- 多線程原理
- Thread類
- 實現(xiàn)Runnable接口方式創(chuàng)建線程
- Thread和Runnable的區(qū)別
- 匿名內部類方式實現(xiàn)線程的創(chuàng)建
并發(fā)與并行
- 并發(fā):指兩個或多個事件在同一個時間段內發(fā)生。
- 并行:指兩個或多個事件在同一時刻發(fā)生(同時發(fā)生)。
在操作系統(tǒng)中,安裝了多個程序,并發(fā)指的是在一段時間內宏觀上有多個程序同時運行,這在單 CPU 系統(tǒng)中,每一時刻只能有一道程序執(zhí)行,即微觀上這些程序是分時的交替運行,只不過是給人的感覺是同時運行,那是因為分時交替運行的時間是非常短的。
而在多個 CPU 系統(tǒng)中,則這些可以并發(fā)執(zhí)行的程序便可以分配到多個處理器上(CPU),實現(xiàn)多任務并行執(zhí)行,即利用每個處理器來處理一個可以并發(fā)執(zhí)行的程序,這樣多個程序便可以同時執(zhí)行。目前電腦市場上說的多核 CPU,便是多核處理器,核 越多,并行處理的程序越多,能大大的提高電腦運行的效率。
注意:單核處理器的計算機肯定是不能并行的處理多個任務的,只能是多個任務在單個CPU上并發(fā)運行。同理,線程也是一樣的,從宏觀角度上理解線程是并行運行的,但是從微觀角度上分析卻是串行運行的,即一個線程一個線程的去運行,當系統(tǒng)只有一個CPU時,線程會以某種順序執(zhí)行多個線程,我們把這種情況稱之為線程調度。
線程與進程
-
進程:是指一個內存中運行的應用程序,每個進程都有一個獨立的內存空間,一個應用程序可以同時運行多個進程;進程也是程序的一次執(zhí)行過程,是系統(tǒng)運行程序的基本單位;系統(tǒng)運行一個程序即是一個進程從創(chuàng)建、運行到消亡的過程。
-
線程:線程是進程中的一個執(zhí)行單元,負責當前進程中程序的執(zhí)行,一個進程中至少有一個線程。一個進程中是可以有多個線程的,這個應用程序也可以稱之為多線程程序。
簡而言之:一個程序運行后至少有一個進程,一個進程中可以包含多個線程
我們可以再電腦底部任務欄,右鍵----->打開任務管理器,可以查看當前任務的進程:
進程
線程
線程調度:
-
分時調度
所有線程輪流使用 CPU 的使用權,平均分配每個線程占用 CPU 的時間。
-
搶占式調度
優(yōu)先讓優(yōu)先級高的線程使用 CPU,如果線程的優(yōu)先級相同,那么會隨機選擇一個(線程隨機性),Java使用的為搶占式調度。
- 設置線程的優(yōu)先級
- 搶占式調度詳解
大部分操作系統(tǒng)都支持多進程并發(fā)運行,現(xiàn)在的操作系統(tǒng)幾乎都支持同時運行多個程序。比如:現(xiàn)在我們上課一邊使用編輯器,一邊使用錄屏軟件,同時還開著畫圖板,dos窗口等軟件。此時,這些程序是在同時運行,”感覺這些軟件好像在同一時刻運行著“。
實際上,CPU(中央處理器)使用搶占式調度模式在多個線程間進行著高速的切換。對于CPU的一個核而言,某個時刻,只能執(zhí)行一個線程,而 CPU的在多個線程間切換速度相對我們的感覺要快,看上去就是在同一時刻運行。
其實,多線程程序并不能提高程序的運行速度,但能夠提高程序運行效率,讓CPU的使用率更高。
創(chuàng)建線程類
Java使用java.lang.Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例。每個線程的作用是完成一定的任務,實際上就是執(zhí)行一段程序流即一段順序執(zhí)行的代碼。Java使用線程執(zhí)行體來代表這段程序流。Java中通過繼承Thread類來創(chuàng)建并啟動多線程的步驟如下:
代碼如下:
測試類:
public class Demo01Thread {public static void main(String[] args) {//創(chuàng)建自定義線程對象MyThread mt = new MyThread("線程0");MyThread mt1 = new MyThread("線程1");//開啟新線程mt.start();mt1.start();//在主方法中執(zhí)行for循環(huán)for (int i = 0; i < 10; i++) {System.out.println("main線程!" + i);}} }自定義線程類:
public class MyThread extends Thread {//定義指定線程名稱的構造方法public MyThread(String name) {//調用父類的String參數(shù)的構造方法,指定線程的名稱super(name);}/*** 重寫run方法,完成該線程執(zhí)行的邏輯*/@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(getName()+":正在執(zhí)行!"+i);}} }
結果可以看出各個線程隨機執(zhí)行。
多線程原理
上述代碼流程圖:
- 程序啟動運行main的時候,java虛擬機啟動一個進程,主線程main在main()調用時候創(chuàng)建。隨著調用mt對象的start方法,一個新的線程就啟動了,這樣就是多個線程在并發(fā)運行了。
- 通過上圖可以很清晰看到多線程執(zhí)行過程。
- 下面進行圖解說明多個線程為何可以完成并發(fā)執(zhí)行。
當執(zhí)行線程的任務結束了,線程就會自動在棧內存中釋放。但是當所有的線程都執(zhí)行完畢時,進程就結束了
Thread類
構造方法:
- public Thread():分配一個新的線程對象
- public Thread(String name):分配一個指定名字的新的線程對象
- public Thread(Runnable target):分配一個帶指定目標新的線程對象
- public Thread(Runnable target,String name):分配一個帶有新的名字,指定目標的新的線程對象。
常用方法:
- public String getName():獲取當前線程名稱
- public void start():啟動此線程,java虛擬機調用run方法
- public void run():此線程執(zhí)行時的任務代碼
- public static void sleep(long millis):使當前線程以指定毫秒數(shù)暫停
- public statc Thread currentThread():返回當前正在執(zhí)行的線程對象的引用
實現(xiàn)Runnable接口方式創(chuàng)建線程
采用java.lang.Runnable創(chuàng)建線程也是非常常用的一種,只需要重寫run方法即可。
步驟代碼如下:
創(chuàng)建MyRunnable類調用Runnable接口
創(chuàng)建Runnable實現(xiàn)類的實例,并以此實例作為Thread的target來創(chuàng)建Thread對象,該Thread才是真正的線程對象。
public class Demo02Runnable {public static void main(String[] args) {//創(chuàng)建自定義類對象, 線程任務對象MyRunnable mr = new MyRunnable();//創(chuàng)建線程對象Thread t = new Thread(mr,"伊澤瑞爾");t.start();for (int i = 0; i <20; i++) {System.out.println("拉克絲"+"-"+i);}} }- 通過實現(xiàn)Runnable接口,使得該類有了多線程類的特征。run()方法是多線程程序的一 個執(zhí)行目標。所有的多線程代碼都在run方法里面。Thread類實際 上也是實現(xiàn)了’Runnable接口的類。
- 在啟動的多線程的時候,需要先通過Thread類的構造方 法Thread(Runnable target)構造出對象,然后調用Thread對象的start0方法來運行多線程代碼。
- 實際上所有的多線程代碼都是通過運行Thread的start()方法來運行的。因此,不管是繼承Thread類還是實現(xiàn)Runnable接口來實現(xiàn)多線程,最終還是通過Thread的對象的API來控制線程的,熟悉Thread類的API是進行多線程
編程的基礎。
Thread和Runnable的區(qū)別
如果一個類繼承Thread,則不適合資源共享。但是如果實現(xiàn)了Runable接口的話,則很容易的實現(xiàn)資源共享。
總結:
實現(xiàn)Runnable接口比繼承Thread類所具有的優(yōu)勢:
擴充:在java中, 每次程序運行至少啟動2個線程。一個是main線程-一個是垃圾收集線程。因為每當使用java命令執(zhí)行一個類的時候, 實際上都會啟動一個JVM, 每一個JVM其實在就是在操作系統(tǒng)中啟動了一個進程。
匿名內部類方式實現(xiàn)線程的創(chuàng)建
public class Demo03InnerClassTread {public static void main(String[] args) {new Thread(){@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println("線程1---"+i);}}}.start();Runnable r = new Runnable() {@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println("線程2---"+i);}}};new Thread(r).start();} }總結
以上是生活随笔為你收集整理的(Java多线程)多线程原理和使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (仿头条APP项目)7.首页标签页完善和
- 下一篇: (仿头条APP项目)8.新闻详情页面实现