您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java并發(fā)編程的基礎(chǔ)知識有哪些的相關(guān)知識點,內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
首先還是的了解一下線程的基礎(chǔ),這邊文章將帶著大家來了解一下線程的基礎(chǔ)知識。
實現(xiàn) Runnable 接口
繼承 Thread 類
實現(xiàn) Callable 接口通過 FutureTask 包裝器來創(chuàng)建線程
通過線程池創(chuàng)建線程
下面將用線程池和 Callable 的方式來創(chuàng)建線程
public class CallableDemo implements Callable<String> { @Override public String call() throws Exception { int a=1; int b=2; System. out .println(a+b); return "執(zhí)行結(jié)果:"+(a+b); } public static void main(String[] args) throws ExecutionException, InterruptedException { //創(chuàng)建一個可重用固定線程數(shù)為1的線程池 ExecutorService executorService = Executors.newFixedThreadPool (1); CallableDemo callableDemo=new CallableDemo(); //執(zhí)行線程,用future來接收線程的返回值 Future<String> future = executorService.submit(callableDemo); //打印線程的返回值 System. out .println(future.get()); executorService.shutdown(); } }
執(zhí)行結(jié)果
3 執(zhí)行結(jié)果:3
NEW:初始狀態(tài),線程被構(gòu)建,但是還沒有調(diào)用 start 方法。
RUNNABLED:運行狀態(tài),JAVA 線程把操作系統(tǒng)中的就緒和運行兩種狀態(tài)統(tǒng)一稱為“運行中”。調(diào)用線程的 start() 方法使線程進(jìn)入就緒狀態(tài)。
BLOCKED:阻塞狀態(tài),表示線程進(jìn)入等待狀態(tài),也就是線程因為某種原因放棄了 CPU 使用權(quán)。比如訪問 synchronized 關(guān)鍵字修飾的方法,沒有獲得對象鎖。
Waiting :等待狀態(tài),比如調(diào)用 wait() 方法。
TIME_WAITING:超時等待狀態(tài),超時以后自動返回。比如調(diào)用 sleep(long millis) 方法
TERMINATED:終止?fàn)顟B(tài),表示當(dāng)前線程執(zhí)行完畢。
看下源碼:
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
線程的最小優(yōu)先級:1
線程的最大優(yōu)先級:10
線程的默認(rèn)優(yōu)先級:5
通過調(diào)用 getPriority() 和 setPriority(int newPriority) 方法來獲得和設(shè)置線程的優(yōu)先級
看下源碼:
/** * The minimum priority that a thread can have. */ public final static int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public final static int MAX_PRIORITY = 10;
看下代碼:
public class ThreadA extends Thread { public static void main(String[] args) { ThreadA a = new ThreadA(); System.out.println(a.getPriority());//5 a.setPriority(8); System.out.println(a.getPriority());//8 } }
線程優(yōu)先級特性:
繼承性:比如 A 線程啟動 B 線程,則B線程的優(yōu)先級與 A 是一樣的。
規(guī)則性:高優(yōu)先級的線程總是大部分先執(zhí)行完,但不代表高優(yōu)先級線程全部先執(zhí)行完。
隨機性:優(yōu)先級較高的線程不一定每一次都先執(zhí)行完。
stop() 方法,這個方法已經(jīng)標(biāo)記為過時了,強制停止線程,相當(dāng)于 kill -9。
interrupt() 方法,優(yōu)雅的停止線程。告訴線程可以停止了,至于線程什么時候停止,取決于線程自身。
看下停止線程的代碼:
public class InterruptDemo { private static int i ; public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { //默認(rèn)情況下isInterrupted 返回 false、通過 thread.interrupt 變成了 true while (!Thread.currentThread().isInterrupted()) { i++; } System.out.println("Num:" + i); }, "interruptDemo"); thread.start(); TimeUnit.SECONDS.sleep(1); thread.interrupt(); //不加這句,thread線程不會停止 } }
看上面這段代碼,主線程 main 方法調(diào)用 thread線程的 interrupt() 方法,就是告訴 thread 線程,你可以停止了(其實是將 thread 線程的一個屬性設(shè)置為了 true ),然后 thread 線程通過 isInterrupted() 方法獲取這個屬性來判斷是否設(shè)置為了 true。這里我再舉一個例子來說明一下,
看代碼:
public class ThreadDemo { private volatile static Boolean interrupt = false ; private static int i ; public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { while (!interrupt) { i++; } System.out.println("Num:" + i); }, "ThreadDemo"); thread.start(); TimeUnit.SECONDS.sleep(1); interrupt = true; } }
是不是很相似,再簡單總結(jié)一下:
當(dāng)其他線程通過調(diào)用當(dāng)前線程的 interrupt 方法,表示向當(dāng)前線程打個招呼,告訴他可以中斷線程的執(zhí)行了,并不會立即中斷線程,至于什么時候中斷,取決于當(dāng)前線程自己。
線程通過檢查自身是否被中斷來進(jìn)行相應(yīng),可以通過 isInterrupted() 來判斷是否被中斷。
這種通過標(biāo)識符來實現(xiàn)中斷操作的方式能夠使線程在終止時有機會去清理資源,而不是武斷地將線程停止,因此這種終止線程的做法顯得更加安全和優(yōu)雅。
兩種復(fù)位方式:
Thread.interrupted()
通過拋出 InterruptedException 的方式
然后了解一下什么是復(fù)位:
線程運行狀態(tài)時 Thread.isInterrupted() 返回的線程狀態(tài)是 false,然后調(diào)用 thread.interrupt() 中斷線程 Thread.isInterrupted() 返回的線程狀態(tài)是 true,最后調(diào)用 Thread.interrupted() 復(fù)位線程Thread.isInterrupted() 返回的線程狀態(tài)是 false 或者拋出 InterruptedException 異常之前,線程會將狀態(tài)設(shè)為 false。
下面來看下兩種方式復(fù)位線程的代碼,首先是 Thread.interrupted() 的方式復(fù)位代碼:
public class InterruptDemo { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { while (true) { //Thread.currentThread().isInterrupted()默認(rèn)是false,當(dāng)main方式執(zhí)行thread.interrupt()時,狀態(tài)改為true if (Thread.currentThread().isInterrupted()) { System.out.println("before:" + Thread.currentThread().isInterrupted());//before:true Thread.interrupted(); // 對線程進(jìn)行復(fù)位,由 true 變成 false System.out.println("after:" + Thread.currentThread().isInterrupted());//after:false } } }, "interruptDemo"); thread.start(); TimeUnit.SECONDS.sleep(1); thread.interrupt(); } }
拋出 InterruptedException 復(fù)位線程代碼:
public class InterruptedExceptionDemo { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); // break; } } }, "interruptDemo"); thread.start(); TimeUnit.SECONDS.sleep(1); thread.interrupt(); System.out.println(thread.isInterrupted()); } }
結(jié)果:
false java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at com.cl.concurrentprogram.InterruptedExceptionDemo.lambda$main$0(InterruptedExceptionDemo.java:16) at java.lang.Thread.run(Thread.java:748)
需要注意的是,InterruptedException 異常的拋出并不意味著線程必須終止,而是提醒當(dāng)前線程有中斷的操作發(fā)生,至于接下來怎么處理取決于線程本身,比如
直接捕獲異常不做任何處理
將異常往外拋出
停止當(dāng)前線程,并打印異常信息
像我上面的例子,如果拋出 InterruptedException 異常,我就break跳出循環(huán)讓 thread 線程終止。
為什么要復(fù)位:
Thread.interrupted() 是屬于當(dāng)前線程的,是當(dāng)前線程對外界中斷信號的一個響應(yīng),表示自己已經(jīng)得到了中斷信號,但不會立刻中斷自己,具體什么時候中斷由自己決定,讓外界知道在自身中斷前,他的中斷狀態(tài)仍然是 false,這就是復(fù)位的原因。
以上就是“Java并發(fā)編程的基礎(chǔ)知識有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。