1. 程式人生 > >java 執行緒開啟 中斷

java 執行緒開啟 中斷

1.cpu時間片輪轉機制

  計算機執行時需要同時執行多個程式,但一個cpu只能同時執行一個程式,為了讓使用者感覺同時多個程式都在執行,需要模擬並行運算,就引入cpu時間片輪轉機制。

  作業系統一般是按照一定策略,定期給每個活動的程序執行其內部程式的機會,並且每次只執行一小段時間,然後作業系統利用中斷強行退出執行,將當前程式資訊壓棧,然後開始執行下一個程序的一小段程式,通過這樣不斷快速的迴圈切換,每個程式都獲得執行。(上下文切換)

  在我們程式設計師看來,只需要理解程式是被作業系統片段執行的,每個片段就是一個時間片,在自己的程式執行時不是獨一無二的,我們看似很順暢的工作,其實是由一個個的執行片段構成的, 我們眼中相鄰的兩條語句甚至同一個語句中兩個不同的運算子之間,都有可能插入其他
執行緒
或程序的動作
。 2.java執行緒   建立執行緒
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 {
        @Override
        
public 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方法後就停止列印了,通過對比印證了上述所說。