多線程與線程池的基本概念與方法

一、多線程

1、什麼是多線程?

線程是操作系統調度的最小單元,在一個進程裏可以創建多個線程,這些線程擁有各自的計數器、堆棧和局部變量等屬性,並且能夠訪問共享的內存變量。處理器在多線程中高速切換,達到“同時運行”的效果。

2、多線程的創建方式

  1. 繼承Thread類
  2. 實現Runnable接口,重寫run()方法
  3. 實現Callable接口,重寫call方法

3、線程的啓動方式

/**
     * 1、繼承Thread
     */
    public void createByThread(){
        Thread thread = new TestThread();
        thread.start();
    }

    /**
     * 2、實現Runnable
     */
    public void createByRunnable(){
        Thread thread = new Thread(new TestRunnable());
        thread.start();
    }

    /**
     * Callable方式
     */
    public String createByCallable() throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask = new FutureTask<String>(new TestCallable());
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get());
        return futureTask.get();
    }

4、線程有什麼狀態

  • NEW :初始化狀態,線程被構建,但沒有調用start()方法。
  • RUNNABLE :運行狀態,java線程將操作系統中的就緒、運行兩個狀態統稱爲運行狀態
  • BLOCKED :阻塞狀態 ,線程阻塞於鎖
  • WAITING:等待狀態,線程進入等待狀態,此時需要其他線程做出一下動作(通知或者中斷)
  • TIME_WAITING:超時等待狀態,可以在指定時間自動返回
  • TERMINATED:終止狀態,線程已經執行完畢。

5、線程如何終止

  • 設置flag進行控制,線程代碼運行完畢
  • 使用stop方法。現在已經過期不建議用,因爲不保證線程資源正常釋放,通常沒有給予線程完成資源釋放工作的機會,因此會導致程序可能工作在不確定狀態下。
  • 結合interrupt和isInterrupted、interrrupted。
    • 中斷可以理解爲線程的一個標識位屬性,它表示線程是否被其他線程進行了中斷操作。其他線程調用interrupt()方法對其進行中斷操作。
    • 線程自身通過調用isInterrunpted()方法判斷是否被中斷,或者調用靜態方法Thread.interrupted對當前線程的中斷標識進行復位。

二、線程池

1、什麼是線程池?

線程池管理多個線程的創建以及銷燬,可以預先的創建多個線程,將提交上來的任務合理分配給線程執行。線程池可以降低資源消耗,提高響應速度以及提高線程的可管理性。

2、幾種線程池的創建

//創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程(保存60s),若無可回收,則新建線程。
ExecutorService executorService =  Executors.newCachedThreadPool();
//創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
ExecutorService executorService2 = Executors.newFixedThreadPool(2);
// 創建一個定長線程池,支持定時及週期性任務執行。
ExecutorService executorService3 = Executors.newScheduledThreadPool(1);
//創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
ExecutorService executorService4 = Executors.newSingleThreadExecutor();

3、線程池的使用

  1. 調用執行器Executors創建線程池
  2. 調用submit()或者execute()方法,傳入線程對象
  3. 當不需要執行線程任務時,調用shutdown關閉線程池
System.out.println("=========線程池的使用=========");
//submit底層調用execute方法執行任務
executorService.submit(new TestThread());
//傳入Runnable
executorService.execute(new TestRunnable());
//傳入Callable 並接收線程返回值
Future<String> future1 = executorService.submit(new TestCallable());
System.out.println("線程池方式啓動Callable結果:"+future1.get());
System.out.println("=====關閉線程池======");
executorService.shutdown();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章