併發程式設計的三種實現方式
阿新 • • 發佈:2018-11-09
java天生就是多執行緒的程式語言,建立新的執行緒有三種實現方式,分別是:
繼承Thread,實現Runable,實現Callable<T>
程式碼如下:
//Thread class ThreadTest extends Thread { @Override public void run() { // TODO Auto-generated method stub super.run(); } } //Callable class CallableTest implements Callable<String> { @Override public String call() throws Exception { // TODO Auto-generated method stub return null; } } //Runnable class RunableTest implements Runnable { @Override public void run() { // TODO Auto-generated method stub } }
三種方式又分別有自己的啟動方式
package com.hyan.client; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class Test { public static void main(String[] args) throws InterruptedException, ExecutionException { // Thread執行 ThreadTest threadTest = new ThreadTest(); threadTest.start(); Thread.sleep(50); threadTest.interrupt(); // Callable執行 CallableTest callableTest = new CallableTest(); FutureTask<String> futureTask = new FutureTask<>(callableTest); Thread thread = new Thread(futureTask); thread.start(); Thread.sleep(50); thread.interrupt(); System.out.println("callable的返回值:" + futureTask.get()); // Runnable執行 RunableTest runableTest = new RunableTest(); Thread runThread = new Thread(runableTest); runThread.start(); Thread.sleep(50); runThread.interrupt(); } } class ThreadTest extends Thread { @Override public void run() { // TODO Auto-generated method stub super.run(); System.out.println(Thread.currentThread().getName() + ">1>>>>>>>>>" + isInterrupted()); while (!isInterrupted()) { try { Thread.sleep(20); System.out.println(Thread.currentThread().getName() + ">1>>>>>>>>>run"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); // 需要在catch中再次呼叫interrupt,這樣才能終止while interrupt(); } } // isInterrupted()是例項方法,是呼叫該方法的物件所表示的那個執行緒的isInterrupted(),不會重置當前執行緒的中斷狀態 System.out.println(Thread.currentThread().getName() + ">1>>>>>>end" + isInterrupted()); // interrupted()是靜態方法:內部實現是呼叫的當前執行緒的isInterrupted(),並且會重置當前執行緒的中斷狀態 Thread.interrupted(); System.out.println(Thread.currentThread().getName() + ">1>>>>>>end改變後的狀態" + isInterrupted()); } } class CallableTest implements Callable<String> { @Override public String call() throws Exception { // TODO Auto-generated method stub while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(20); System.out.println(Thread.currentThread().getName() + ">2>>>>>>>>>run"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); Thread.currentThread().interrupt(); } } System.out.println(Thread.currentThread().getName() + ">2>>>>>>end" + Thread.currentThread().isInterrupted()); return "CallableTest end "; } } class RunableTest implements Runnable { @Override public void run() { // TODO Auto-generated method stub while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(20); System.out.println(Thread.currentThread().getName() + ">3>>>>>>>>>run"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); Thread.currentThread().interrupt(); } } System.out.println(Thread.currentThread().getName() + ">3>>>>>>end" + Thread.currentThread().isInterrupted()); } }
如果要終止一個執行緒,可以使用stop()方法,但是已經被棄用,現在應該使用interrupt來終止執行緒的執行;
開發過程中可以通過interrupt方法改變中斷狀態,線上程中捕捉執行緒的中斷狀態,當isInterrupted()為true時,代表中斷執行緒,但是具體的實現程式碼還需要自己去中斷。
注:
interrupt方法改變中斷狀態也就是isInterrupted()變為true
isInterrupted()判斷執行緒是否需要中斷
interrupted()為靜態方法,用來恢復執行緒的中斷狀態,也就是將isInterrupted()變為false;
Thread-0>1>>>>>>>>>false Thread-0>1>>>>>>>>>run Thread-0>1>>>>>>>>>run Thread-0>1>>>>>>endtrue Thread-0>1>>>>>>end改變後的狀態false java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.hyan.client.ThreadTest.run(Test.java:44) Thread-1>2>>>>>>>>>run Thread-1>2>>>>>>>>>run java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.hyan.client.CallableTest.call(Test.java:73) at com.hyan.client.CallableTest.call(Test.java:1) at java.util.concurrent.FutureTask.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Thread-1>2>>>>>>endtrue callable的返回值:CallableTest end Thread-2>3>>>>>>>>>run Thread-2>3>>>>>>>>>run java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.hyan.client.RunableTest.run(Test.java:96) at java.lang.Thread.run(Unknown Source) Thread-2>3>>>>>>endtrue
當子執行緒中包含了等待,在InterruptedException中應該再次呼叫interrupt方法,這樣才能終止執行緒