多线程java_Java多线程基础
在開始之前,先來搞清楚兩個概念:進程和線程。
進程:進程是具有一定獨立功能的程序關于某個數(shù)據(jù)集合上的一次運行活動,是系統(tǒng)進行資源分配和調度的一個獨立單位。
線程:線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位,線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),一個線程可以創(chuàng)建和撤銷另一個線程;
進程和線程的關系:
(1)一個線程只能屬于一個進程,而一個進程可以有多個線程,但至少有一個線程。
(2)資源分配給進程,同一進程的所有線程共享該進程的所有資源。
(3)線程在執(zhí)行過程中,需要協(xié)作同步。不同進程的線程間要利用消息通信的辦法實現(xiàn)同步。
(4)處理機分給線程,即真正在處理機上運行的是線程。
(5)線程是指進程內的一個執(zhí)行單元,也是進程內的可調度實體。
線程與進程的區(qū)別:
(1)調度:線程作為調度和分配的基本單位,進程作為擁有資源的基本單位。
(2)并發(fā)性:不僅進程之間可以并發(fā)執(zhí)行,同一個進程的多個線程之間也可以并發(fā)執(zhí)行。
(3)擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統(tǒng)資源,但可以訪問隸屬于進程的資源。
(4)系統(tǒng)開銷:在創(chuàng)建或撤銷進程的時候,由于系統(tǒng)都要為之分配和回收資源,導致系統(tǒng)的開銷明顯大于創(chuàng)建或撤銷線程時的開銷。但進程有獨立的地址空間,進程崩潰后,在保護模式下不會對其他的進程產生影響,而線程只是一個進程中的不同的執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉,所以多進程的程序要比多線程的程序健壯,但是在進程切換時,耗費的資源較大,效率要差些。
創(chuàng)建一個線程(Java中提供了三種創(chuàng)建線程的方法):
通過實現(xiàn)Runnable接口;
通過繼承Thread類本身;
通過Callable和Future創(chuàng)建線程。
一、通過實現(xiàn)Runnable接口來創(chuàng)建線程(推薦使用)
實現(xiàn)Java.lang.Runnable接口,并重寫run()方法。
優(yōu)勢:可繼承其它類,多線程可共享同一個Thread對象;
劣勢:編程方式稍微復雜,如需訪問當前線程,需調用Thread.currentThread()方法。
package結果:
main線程 main線程 Thread-0線程 main線程 Thread-0線程 main線程 Thread-0線程 main線程 Thread-0線程 Thread-0線程二、通過繼承Thread類本身來創(chuàng)建線程(不推薦使用==>Java中單繼承的局限性)
繼承Java.lang.Thread類,并覆蓋run() 方法。
優(yōu)勢:編寫簡單;
劣勢:無法繼承其它父類
package com.bjwyj.thread; /*** 創(chuàng)建線程二:* 1、繼承Thread+重寫run* 2、啟動:創(chuàng)建子類對象+start* @author 吳永吉**/ public class ThreadDemo02 extends Thread{/*** 線程入口點*/@Overridepublic void run() {for(int i=0;i<5;i++) {System.out.println(Thread.currentThread().getName()+"線程");}}public static void main(String[] args) {//創(chuàng)建子類對象ThreadDemo02 td = new ThreadDemo02();//啟動td.start(); //不保證立即運行,CPU調用for(int i=0;i<5;i++) {System.out.println(Thread.currentThread().getName()+"線程");}} }結果:
Thread-0線程 main線程 main線程 Thread-0線程 main線程 Thread-0線程 Thread-0線程 Thread-0線程 main線程 main線程三、通過Callable和Future創(chuàng)建線程(屬于JUC高級編程,初學者了解即可)
實現(xiàn)Callable接口,重寫call方法。
優(yōu)勢:性能更優(yōu)。
劣勢:編寫復雜。
package com.bjwyj.thread;import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;/*** 了解創(chuàng)建線程的方式三* @author 吳永吉**/ public class ThreadDemo03 implements Callable<String>{String name; //名字public ThreadDemo03(String name) {this.name = name;}@Overridepublic String call() throws Exception {return this.name;}public static void main(String[] args) throws InterruptedException, ExecutionException {ThreadDemo03 td1 = new ThreadDemo03("線程1");ThreadDemo03 td2 = new ThreadDemo03("線程2");ThreadDemo03 td3 = new ThreadDemo03("線程3");//創(chuàng)建執(zhí)行服務ExecutorService ser = Executors.newFixedThreadPool(3);//提交任務Future<String> result1 = ser.submit(td1);Future<String> result2 = ser.submit(td2);Future<String> result3 = ser.submit(td3);//獲取結果String r1 = result1.get();String r2 = result2.get();String r3 = result3.get();System.out.println(r1);System.out.println(r2);System.out.println(r3);//關閉服務ser.shutdownNow();} }結果:
線程1 線程2 線程3從以上方式一和方式二可以看出:各個線程之間幾乎是穿插著運行并輸出的,那么,多線程情況下,難道真的是同時在運行嗎?答案不是絕對的。首先,一個處理器(CPU)在某一個時間點上永遠都只能是一個線程!雙核CPU可以理解為兩塊CPU,4核,8核等依次類推,就單個CPU而言,某個時間點只能是一個線程在運行,所謂的多線程是通過調度獲取CPU的時間片實現(xiàn)的。其實就相當于CPU是一個人,多線程是幾件事,CPU一下子干這件事,干一會時間片到了就干另一件。由于CPU計算速度很快很快,所以看起來就像是幾件事情在同時做著。不過現(xiàn)在CPU都是雙核四核八核的,這些是真的一起干的,因為這是幾個人干幾件事,所以,多CPU當然是真多線程。
線程是一個動態(tài)執(zhí)行的過程,它也有一個從產生到死亡的過程,線程生命周期有五種狀態(tài):
新建(new Thread)
當創(chuàng)建Thread類的一個實例(對象)時,此線程進入新建狀態(tài)(未被啟動)。
例如:Thread t1=new Thread();
就緒(runnable)
線程已經(jīng)被啟動,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊等候得到CPU資源。
例如:t1.start();
運行(running)
線程獲得CPU資源正在執(zhí)行任務(run()方法),此時除非此線程自動放棄CPU資源或者有優(yōu)先級更高的線程進入,線程將一直運行到結束。
死亡(dead)
當線程執(zhí)行完畢或被其它線程殺死,線程就進入死亡狀態(tài),這時線程不可能再進入就緒狀態(tài)等待執(zhí)行。
自然終止:正常運行run()方法后終止。
異常終止:調用stop()(已棄用)方法讓一個線程終止運行。
堵塞(blocked)
由于某種原因導致正在運行的線程讓出CPU并暫停自己的執(zhí)行,即進入堵塞狀態(tài)。
正在睡眠:用sleep(long t) 方法可使線程進入睡眠方式。一個睡眠著的線程在指定的時間過去可進入就緒狀態(tài)。
正在等待:調用wait()方法。(調用notify()方法回到就緒狀態(tài))
被另一個線程所阻塞:調用suspend()(已棄用)方法。(調用resume()(已棄用)方法恢復)
總結
以上是生活随笔為你收集整理的多线程java_Java多线程基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jar包导出无法显示图片或者音乐_音乐曲
- 下一篇: 三丰三坐标编程基本步骤_数控车床编程,经