1,線程基礎

一,線程與進程

線程java

進程中負責程序執行的執行單元,線程自己依靠程序進行運行,線程是程序中的順序控制流,只能使用分配給程序的資源和環境。緩存

進程多線程

執行中的程序,一個進程至少包含一個線程。ide

二,線程的生命週期

線程是一個動態執行的過程,它也有一個從產生到死亡的過程。下圖顯示了一個線程完整的生命週期: 測試

1,初始化狀態spa

當使用new關鍵字Thread 類、其子類創建一個線程對象後,該線程對象就處於初始化狀態線程

2,就緒狀態3d

當線程對象調用了start()方法以後,該線程就進入就緒狀態就緒狀態的線程處於就緒隊列中,要等待JVM裏線程調度器的調度。code

3,運行狀態對象

就緒狀態的線程獲取 CPU 資源,就能夠執行 run(),此時線程便處於運行狀態

4,超時等待狀態

運行狀態中的線程執行sleep()方法,此時線程進入到超時等待狀態

5,等待狀態

運行狀態中的線程執行wait()方法,此時線程進入到等待狀態

6,阻塞狀態

運行狀態中的線程遇到I/O 請求、同步代碼塊,此時線程進入到阻塞狀態

7,死亡狀態

一個運行狀態的線程完成任務或者其餘終止條件發生時,該線程就切換到終止狀態

線程中有一個枚舉類型,包括了全部的線程狀態:

public enum State {
    //NEW狀態表示線程剛剛被定義,還未實際得到資源以啓動,也就是還未調用start()方法。
    NEW,
    //RUNNABLE表示線程當前處於運行狀態,固然也有可能因爲時間片使用完了而等待CPU從新的調度。
    RUNNABLE,
    //BLOCKED表示線程在競爭某個鎖失敗時被置於阻塞狀態。
    BLOCKED,
    //WAITING和TIMED_WAITING表示線程在運行中因爲缺乏某個條件而不得不被置於條件等待隊列,等待須要的條件或資源。
    WAITING,
    TIMED_WAITING,
    //TERMINATED表示線程運行結束,當線程的run方法結束以後,該線程就會是TERMINATED狀態。
    TERMINATED;
}

在代碼中咱們能夠經過調用線程的getState()方法獲取當前線程的狀態。

二,建立線程的多種方式

1,繼承Thread類

建立一個新的類,該類繼承 Thread 類,而後建立一個該類的實例。在java.lang包中定義, 繼承Thread類必須重寫run()方法,該方法是新線程的入口點。它也必須調用 start() 方法才能執行。

/**
 * 
 * @類名稱:Thread1
 * @類描述:經過繼承Thread來實現多線程.
 * @建立人:Zender
 */
public class Thread1 extends Thread{
    @Override
    public void run() {
        System.err.println("經過繼承Thread來實現多線程.");
    }
}

其本質上是實現了 Runnable 接口的一個實例:

2,實現Runnable接口

/**
 * 
 * @類名稱:Thread2
 * @類描述:經過實現Runnable來實現多線程.
 * @建立人:Zender
 */
public class Thread2 implements Runnable{
    public void run() {
        System.err.println("經過實現Runnable來實現多線程.");
    }
}

3,經過匿名內部類的方式建立線程

匿名內部類建立的線程只會執行一次

public static void main(String[] args) {
    //第一種
    /*new Thread() {
        public void run() {
            System.out.println("thread start ..");
        };
    }.start();*/
    
    //第二種
    /*new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("thread start ..");
        }
    }).start();*/
    
    //第三種
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("runnable");
        }
    })
    }.start();
}

4,經過 Callable 和 Future 建立線程

1. 建立 Callable 接口的實現類,並實現 call() 方法,該 call() 方法將做爲線程執行體,而且有返回值。

2. 建立 Callable 實現類的實例,使用 FutureTask 類來包裝 Callable 對象,該 FutureTask 對象封裝了該 Callable 對象的 call() 方法的返回值。

3. 使用 FutureTask 對象做爲 Thread 對象的 target 建立並啓動新線程。

4. 調用 FutureTask 對象的 get() 方法來得到子線程執行結束後的返回值。

/**
 * 
 * @類名稱:Thread3
 * @類描述:經過 Callable 和 Future 建立線程.
 * @建立人:Zender
 */
public class Thread3 implements Callable<Integer>{
    //該方法將做爲線程執行體,而且有返回值。
    @Override
    public Integer call() throws Exception {
        int i = 100;
        System.err.println("經過 Callable 和 Future 建立線程.i=" + i);
        return i;
    }
}

TestMain.java

/**
 * 
 * @類名稱:TestMain
 * @類描述:測試
 * @建立人:Zender
 */
public class TestMain {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Thread3 thread3 = new Thread3();
        FutureTask<Integer> ft = new FutureTask<Integer>(thread3);
        new Thread(ft).start();
        System.out.println("線程的返回值:" + ft.get());  
    }
}

4,經過定時器建立線程

不延遲的每秒鐘執行一次指定的線程

public static void main(String[] args) {
    Timer timer = new Timer();
    //Timer.schedule(TimerTask task,long delay,long period)
    //安排指定的任務(task)從指定延遲後的時間(delay)開始進行重複且固定的時間(period)執行.
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            // 實現定時任務
            System.out.println("timertask is run");
        }
    }, 0, 1000);
}

5,經過線程池建立線程

public static void main(String[] args) {
    //建立一個可緩存線程池,若是線程池長度超過處理須要,可靈活回收空閒線程,若無可回收,則新建線程。
    ExecutorService threadPool = Executors.newCachedThreadPool();
    for (int i = 0; i < 100; i++) {
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        });
    }
    //關閉線程池
    threadPool.shutdown();
}

三,Thread經常使用方法

下表列出了Thread類的一些重要方法:

public void start()

使該線程開始執行;Java 虛擬

public void run()

若是該線程是使用獨立的 Runnable 運行對象構造的,則調用該 Runnable 對象的 run 方法;不然,該方法不執行任何操做並返回。

public final void setName(String name)

改變線程名稱。

public final void setPriority(int priority)

更改線程的優先級。

public final void setDaemon(boolean on)

將該線程標記爲守護線程或用戶線程。

public final void join(long millisec)

等待該線程終止的時間最長爲 millis 毫秒。

public void interrupt()

中斷線程。

public final boolean isAlive()

測試線程是否處於活動狀態。

public static void yield()

暫停當前正在執行的線程對象,並執行其餘線程。

public static void sleep(long millisec)

在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行),此操做受到系統計時器和調度程序精度和準確性的影響。

public static boolean holdsLock(Object x)

當且僅當當前線程在指定的對象上保持監視器鎖時,才返回 true。

public static Thread currentThread()

返回對當前正在執行的線程對象的引用。

public static void dumpStack()

將當前線程的堆棧跟蹤打印至標準錯誤流。

相關文章
相關標籤/搜索