java 執行緒開啟 中斷
阿新 • • 發佈:2018-11-24
1.cpu時間片輪轉機制
計算機執行時需要同時執行多個程式,但一個cpu只能同時執行一個程式,為了讓使用者感覺同時多個程式都在執行,需要模擬並行運算,就引入cpu時間片輪轉機制。
作業系統一般是按照一定策略,定期給每個活動的程序執行其內部程式的機會,並且每次只執行一小段時間,然後作業系統利用中斷強行退出執行,將當前程式資訊壓棧,然後開始執行下一個程序的一小段程式,通過這樣不斷快速的迴圈切換,每個程式都獲得執行。(上下文切換)
在我們程式設計師看來,只需要理解程式是被作業系統片段執行的,每個片段就是一個時間片,在自己的程式執行時不是獨一無二的,我們看似很順暢的工作,其實是由一個個的執行片段構成的, 我們眼中相鄰的兩條語句甚至同一個語句中兩個不同的運算子之間,都有可能插入其他package com.ljj.study; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class MyThread { private static class ExtendThread extends Thread { @Overridepublic void run() { System.out.println("ExtendThread running "); System.out.println("id: " + Thread.currentThread().getId()); } } private static class RunThread implements Runnable { public void run() { System.out.println("RunThread running "); System.out.println("id: " + Thread.currentThread().getId()); } } private static class CallThread implements Callable<String> { public String call() throws Exception { System.out.println("CallThread running "); System.out.println("id: " + Thread.currentThread().getId()); return "callresult"; } } public static void main(String[] args) throws InterruptedException, ExecutionException { ExtendThread eh = new ExtendThread(); Thread th0 = new Thread(eh); RunThread rt = new RunThread(); Thread th1 = new Thread(rt); CallThread ct = new CallThread(); FutureTask<String> ft = new FutureTask<String>(ct); Thread th2 = new Thread(ft); th0.start(); th1.start(); th2.start(); System.out.println(ft.get()); } }
RunThread running id: 13 CallThread running id: 14 ExtendThread running callresult id: 12 +++++++++++++++ ExtendThread running CallThread running id: 12 RunThread running id: 13 id: 14 callresult
多次執行程式碼中main方法,發現每次列印結果都不一樣,印證了相鄰的兩條語句甚至同一個語句中兩個不同的運算子之間,都有可能插入其他執行緒或程序的動作。
一般使用實現runnable介面(多實現)和callable介面(有返回值)的方法來建立執行緒
3.執行緒中斷
stop(),resume(),suspend()已不建議使用,stop()會導致執行緒不會正確釋放資源,suspend()容易導致死鎖。
java執行緒是協作式,而非搶佔式
呼叫一個執行緒的interrupt() 方法中斷一個執行緒,並不是強行關閉這個執行緒,只是跟這個執行緒打個招呼,將執行緒的中斷標誌位置為true,執行緒是否中斷,由執行緒本身決定。
isInterrupted() 判定當前執行緒是否處於中斷狀態。
static方法interrupted() 判定當前執行緒是否處於中斷狀態,同時中斷標誌位改為false。
那麼如何理解執行緒是否中斷由執行緒本身決定?
package com.ljj.study; public class EndThread { private static class MyEndThread implements Runnable { public void run() { while (true) { System.out.println(Thread.currentThread().getName() + " running "); } } } private static class MyEndThread1 implements Runnable { public void run() { while (!Thread.currentThread().isInterrupted()) { System.out.println(Thread.currentThread().getName() + " running "); } System.out.println(Thread.currentThread().isInterrupted()); } } public static void main(String[] args) throws InterruptedException { // MyEndThread met = new MyEndThread(); // Thread t0 = new Thread(met); // t0.start(); // // System.out.println("begin "); // t0.interrupt(); MyEndThread1 met1 = new MyEndThread1(); Thread t1 = new Thread(met1); t1.start(); t1.sleep(30); System.out.println("begin "); t1.interrupt(); } }
t0執行緒雖然執行了interrupt方法,但是還是一直在列印,t1執行緒interrupt方法後就停止列印了,通過對比印證了上述所說。