1. 程式人生 > >JDK執行緒池學習筆記-1

JDK執行緒池學習筆記-1

之前使用用過執行緒池,但是就是看看文件介面複製貼上過來用用而已,沒有認真學習過,最近比較好奇執行緒池想學習一下,所以在此做個筆記。

JDK併發包中的執行緒池有:

 ExecutorService single = Executors.newSingleThreadExecutor();

 ExecutorService fixed = Executors.newFixedThreadPool(5);

 ExecutorService cached = Executors.newCachedThreadPool();

 ExecutorService scheduled = Executors.newScheduledThreadPool(5);


分別是:建立一個只有一個執行緒的執行緒池執行任務,沒有得到執行的任務儲存到佇列中。

  建立一個固定大小的執行緒池,上面建立了5個執行緒的執行緒池。

建立一個快取執行緒池,只要有任務沒有執行緒處理就會建立執行緒處理,當有大量閒置執行緒時候根據策略銷燬一些執行緒(策略此處不展開,以後描述)。

建立一個支援排程,定時的執行緒池,指定5個執行緒,支援增加執行緒。

接下來看一下JDK執行緒池的繼承結構:

其中Executor是一個執行器,只有一個execute方法,原始碼如下:

package java.util.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

public interface Executor {
	void execute(Runnable command);
}

ExecutorService是一個執行服務,只要包含的是任務的提交,執行緒池關閉等操作,JDK原始碼如下:

package java.util.concurrent;

import java.util.List;
import java.util.Collection;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;

public interface ExecutorService extends Executor {

	void shutdown();

	List<Runnable> shutdownNow();

	boolean isShutdown();

	boolean isTerminated();

	boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;

	<T> Future<T> submit(Callable<T> task);

	<T> Future<T> submit(Runnable task, T result);

	Future<?> submit(Runnable task);

	<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;

	<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
			throws InterruptedException;

	<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;

	<T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
			throws InterruptedException, ExecutionException, TimeoutException;
}


AbstractExecutorService抽象類是對ExecutorService的部分方法實現,原始碼就不貼上了。

ScheduledExecutorService介面繼承了ExecutorService介面的一些方法宣告,之後又添加了一些自己的排程,定時方法等特性。

ScheduledThreadPoolExecutor便是對ScheduledExecutorService的實現,同時繼承至ThreadPoolExecutor,來支援一些非定時任務的執行特性。

這就是執行緒池的巨集觀繼承結構。

接下來看一些具體實現,下面是簡單入門的一個示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolStudy {

	public static void main(String[] args) {

		ExecutorService scheduled = Executors.newSingleThreadExecutor();

		single.submit(new RunnableDemo());
		
		single.shutdown();

	}

}

class RunnableDemo implements Runnable {

	@Override
	public void run() {
		System.out.println("run ...");
	}

}


建立一個了一個單個執行緒的執行緒池,然後提交任務執行完畢之後關閉執行緒池。

第一步建立單個執行緒的執行緒池時候呼叫的是Executors的newSingleThreadExecutor方法。

newSingleThreadExecutor方法原始碼如下:

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
    }


發現內部建立了一個FinalizableDelegatedExecutorService物件,檢視FinalizableDelegatedExecutorService聲明發現:FinalizableDelegatedExecutorService繼承於DelegatedExecutorService類。原始碼如下(java.util.concurrent.Executors.FinalizableDelegatedExecutorService):

    static class FinalizableDelegatedExecutorService//  是Executors的一個內部類
        extends DelegatedExecutorService {
        FinalizableDelegatedExecutorService(ExecutorService executor) {
            super(executor);
        }
        protected void finalize() {
            super.shutdown();
        }
    }

檢視原始碼便知道FinalizableDelegatedExecutorService作用主要是在垃圾回收時候銷燬執行緒。

在檢視其父類原始碼,也是Executors的一個內部類,實現如下:

 static class DelegatedExecutorService extends AbstractExecutorService {
        private final ExecutorService e;
        DelegatedExecutorService(ExecutorService executor) { e = executor; }
        public void execute(Runnable command) { e.execute(command); }
        public void shutdown() { e.shutdown(); }
        public List<Runnable> shutdownNow() { return e.shutdownNow(); }
        public boolean isShutdown() { return e.isShutdown(); }
        public boolean isTerminated() { return e.isTerminated(); }
        public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
            return e.awaitTermination(timeout, unit);
        }
        public Future<?> submit(Runnable task) {
            return e.submit(task);
        }
        public <T> Future<T> submit(Callable<T> task) {
            return e.submit(task);
        }
        public <T> Future<T> submit(Runnable task, T result) {
            return e.submit(task, result);
        }
        public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
            throws InterruptedException {
            return e.invokeAll(tasks);
        }
        public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                             long timeout, TimeUnit unit)
            throws InterruptedException {
            return e.invokeAll(tasks, timeout, unit);
        }
        public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
            throws InterruptedException, ExecutionException {
            return e.invokeAny(tasks);
        }
        public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                               long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException {
            return e.invokeAny(tasks, timeout, unit);
        }
    }

重點:由於Single執行緒池的功能比較簡單, 返回代理物件目的是遮蔽掉掉newSingle***不需要的方法

由註釋可以知道DelegatedExecutorService類職責是:一個包裝類,用來僅暴露ExecutorService實現類中的ExecutorService的方法,本例項中不適用代理的話正常應該返回一個ThreadPoolExecutor物件,但是由於不想暴露ThreadPoolExecutor的所有方法,所以返回代理物件。

同理:DelegatedScheduledExecutorService是ScheduledThreadPoolExecutor的一個代理類,不想暴露ScheduledExecutorService的所有方法。

		// FinalizableDelegatedExecutorService
		System.out.println(Executors.newSingleThreadExecutor());


		// DelegatedScheduledExecutorService
		System.out.println(Executors.newSingleThreadScheduledExecutor());

以上都是返回代理物件!

拓展,代理的實現:把被代理物件放到代理物件中,作為一個私有成員變數,然後對被代理的物件的部分想暴露出來的方法在代理物件中實現即可!

備註:ThreadPoolExecutor是一個子類 ,它使用執行緒池中執行緒執行提交的任務,ScheduledThreadPoolExecutor也是一個子類 ,它使用執行緒池中執行緒執行提交的任務。

進行小總結:FinalizableDelegatedExecutorService物件就是對代理物件DelegatedExecutorService又包了一層確保垃圾回收銷燬執行緒。

但是FinalizableDelegatedExecutorService卻沒有對DelegatedScheduledExecutorService物件進行包層。具體什麼原因呢?

對於非newSingle***的建立,返回的是對應的Executor:

	       // FinalizableDelegatedExecutorService
		System.out.println(Executors.newSingleThreadExecutor());

		// DelegatedScheduledExecutorService
		System.out.println(Executors.newSingleThreadScheduledExecutor());
		
		// ThreadPoolExecutor
		System.out.println(Executors.newFixedThreadPool(5));

		// ScheduledThreadPoolExecutor
		System.out.println(Executors.newScheduledThreadPool(5));
		
		// ThreadPoolExecutor
		System.out.println(Executors.newCachedThreadPool());

相關推薦

JDK執行學習筆記-1

之前使用用過執行緒池,但是就是看看文件介面複製貼上過來用用而已,沒有認真學習過,最近比較好奇執行緒池想學習一下,所以在此做個筆記。 JDK併發包中的執行緒池有: ExecutorService single = Executors.newSingleThreadEx

JAVA jdk 執行學習筆記

什麼情況下會用到執行緒池呢????? 1. 單個任務處理的時間比較短 2. 將需處理的任務的數量大 使用執行緒池的好處 1.減少在建立和銷燬執行緒上所花的時間以及系統資源的開銷 2.如不使用執行緒池,有可能造成系統建立大量執行緒而導致消耗

JDK執行的拒絕策略

關於新疆服務請求未帶入來話原因的問題        經核查,該問題是由於立單介面內部沒有成功呼叫接續的 “更新來電原因介面”導致的,接續測更新來電原因介面編碼:NGCCT_UPDATESRFLAG_PUT ,立單介面呼叫程式碼如下: fin

執行+JAVA學習筆記-DAY24

24.01_多執行緒(多執行緒的引入)(瞭解) 1.什麼是執行緒 執行緒是程式執行的一條路徑, 一個程序中可以包含多條執行緒 多執行緒併發執行可以提高程式的效率, 可以同時完成多項工作 2.多執行緒的應用場景 紅

C++ 多執行pthread 學習筆記

本篇是我在學習C++多執行緒的時候做的筆記,主要記錄的是基礎的流程,部分程式碼例項,以及重點函式的說明。 pthread 入口函式型別說明 void * func1(void * t) void* 表示無型別指標 void*作為函式引數,表示函式接收一個指標,不管是什麼型別

201711671103《JAVA程式設計》第十二章多執行機制學習筆記

教材學習內容總結 1.執行緒是依附於程序的,程序是分配資源的最小單位,執行緒是比程序更小的執行單位。一個程序可以產生多個執行緒,形成多條執行線索。每條線索,即每個執行緒也有它自身的產生,存在和消亡過程,也是一個動態的概念。 2.JAVA 中的多執行緒機制:多執行緒是指一個應用程式同時存在好幾

執行並行學習筆記

一、執行緒並行相關概念 同步(Synchronous)和非同步(Asynchronous) 同步和非同步的本質區別是是否需要等待,比如一個方法在執行,必須等前面一個方法程執行完成,才可以執行,這就是同步。如果不需要等上一個方法執行完成,並行或者併發執行,這就是非同步呼叫。 併發(Concurrency)

jdk執行總類以及執行的核心引數簡述

JDK自帶執行緒池總類: 1、newFixedThreadPool建立一個指定工作執行緒數量的執行緒池。每當提交一個任務就建立一個工作執行緒,如果工作執行緒數量達到執行緒池初始的最大數,則將提交的任務存入到池佇列中。 2、newCachedThreadPool建立一個可快

執行程式設計學習1)物件及變數的併發訪問

程序:計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統結構的基礎。 執行緒:在程序中獨立執行的子任務。 在java中以下3種方法可以終止正在執行的執行緒: 1) 使用退出標誌,使執行緒正常退出,也就是當run方法完成後執行緒終

RTT執行排程學習筆記

執行緒排程與管理 執行緒執行狀態 執行緒通過呼叫函式rt_thread_create/init進入初始狀態(RT_THREAD_INIT); 再通過呼叫函式rt_thread_startup進入到就緒狀態(RT_THREAD_READY); 當處於執行狀態的執

Android執行學習

在學習執行緒池之前需要先了解幾個java的執行緒池 1.newCachedThreadPool   建立一個可快取執行緒池,根據長度靈活回收,若無空閒執行緒,則新建執行緒 2.newFixedThreadPool  建立一個定長執行緒池,可控制執行緒最大併

網路與執行學習筆記

(1)網路聯機 1.連線:使用者通過建立socket連線來連線伺服器。 要建立Socket連線得知道伺服器的IP地址和埠號。 Socket chatSocket = new Socket("127.0.0.1",5000); 2.傳送:使用者送出資訊給伺服器。 用PrintWriter

【自用】java多執行程式設計學習筆記(程式碼片段來源於網路)

執行緒的基本概念 執行緒是在邏輯上等同於作業系統中說的程序,是程序的細分。比如我們使用同一個軟體同時對電腦進行體檢和防毒的時候,我們就是開啟了那個軟體的程序的兩個執行緒,在邏輯上這兩個執行緒是同時被cpu執行的。 執行緒的生命週期 執行緒的生命週期分為建立,就緒,執行,

java執行學習(六) —— 執行的合理配置

一、確定執行緒數 在工作中,為了加快程式的處理速度,我們需要將問題分解成若干個併發執行的任務。接著我們將這些任務委派給執行緒,以便使它們可以併發的執行。但是需要注意的是,由於資源所限,我們不能建立過多

Boost執行學習筆記

一、建立一個執行緒 建立執行緒 boost::thread myThread(threadFun); 需要注意的是:引數可以是函式物件或者函式指標。並且這個函式無引數,並返回void型別。 當一個thread執行完成時,這個子執行緒就會消失。注意這個執行緒物

執行程式設計學習筆記——執行同步(三)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入執行緒 using System.Diagnostics; namesp

Java執行總結筆記

早上看了篇不錯的介紹執行緒池的文章,細讀了下,筆記如下: 使用執行緒池的好處: 降低資源消耗提高響應速度提高執行緒可管理性執行緒飽和策略: AbortPolicy -直接丟擲異常CallerRunsPolicy -只用呼叫者所在的異常來執行任務DiscardOlde

JDK執行

執行緒池 類繼承關係,方法太多就不列出來了。 Executors Executors扮演執行緒池工廠的角色,ThreadPo

JDK執行簡介與使用

一、執行緒池簡介 為了避免系統頻繁的建立和銷燬執行緒,我們可以將建立的執行緒進行復用。資料庫中的資料庫連線池也是此意。Jav

JAVA學習筆記(併發程式設計 - 捌)- 執行

文章目錄 執行緒池 執行緒池的好處 執行緒池原理 執行緒池狀態 執行緒池常用方法 使用ThreadPoolExecutor建立執行緒池 執行緒池 執行緒資源必須通過執行緒池提供,不允許在應用中