1. 程式人生 > >簡單實現java線程池

簡單實現java線程池

隊列 imp trac poi resize ren .com lsi urn

使用多線程以及線程池的意義無需多說,要想掌握線程池,最好的方法還是自己手動去實現。

一、實現思路

技術分享圖片

                 (網絡盜圖)

總的來說,所有的任務在BlockingQueue中進行等待,由Worker進行具體的操作,Worker才是真正的工作線程。

二、代碼

1、線程池類

package com.ty.thread;
import
java.util.HashSet; import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
/** * @author Taoyong * @date 2018年5月17日 * 天下沒有難敲的代碼! */ public class ThreadPoolExecutor { //維護線程的list private Set<Thread> threadList = new HashSet<Thread>(); /* * 阻塞隊列是線程安全的,主要使用在生產/消費者的場景 */ private BlockingQueue<Task> blockingQueue; //線程池的工作線程數 private
int poolSize = 0; //線程池的核心容量 private int coreSize = 0; private boolean shutDown = false; public ThreadPoolExecutor(int size) { this.poolSize = size; blockingQueue = new LinkedBlockingQueue<>(poolSize); } public void execute(Task task) throws
InterruptedException { if(shutDown == true) { return; } if(coreSize < poolSize) { blockingQueue.offer(task); produceWorker(task); }else { blockingQueue.put(task); } } private void produceWorker(Task task) throws InterruptedException { if(task == null) { throw new NullPointerException("非法參數:傳入的task對象為空!"); } if(shutDown == true) { return; } Thread thread = new Thread(new Worker()); threadList.add(thread); coreSize++; thread.start(); }
public void shutDown() { if(threadList == null || threadList.size() == 0) { return; } shutDown = true; for(Thread thread: threadList) { System.out.println(thread.getName() + " interrupt"); thread.interrupt(); } } /* * 此內部類是實際上的工作線 worker是實現了Runnable接口的實際工作線程,通過while(true)循環從BlockingQueue中取任務執行。 * */ class Worker implements Runnable { @Override public void run() { while(true && shutDown == false) { try { blockingQueue.take().doJob(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }

2、Task類(需要被線程處理的任務類)

package com.ty.thread;

/**
 * @author Taoyong
 * @date 2018年5月17日
 * 天下沒有難敲的代碼!
 */
public class Task {

    //通過taskId對任務進行標識
    private int taskId;
    
    public Task(int taskId) {
        this.taskId = taskId;
    }

    public void doJob() {
        System.out.println("線程" + Thread.currentThread().getName() + "正在處理任務!");
    }

    public int getId() {        
        return taskId;
    }
}

3、測試類

package com.ty.thread;

/**
 * @author Taoyong
 * @date 2018年5月17日
 * 天下沒有難敲的代碼!
 */
public class ThreadPoolExecutorTest {

    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3);
        for(int i = 0; i < 10; i++) {
            Task task = new Task(i);
            threadPoolExecutor.execute(task);                
        }        
        
        threadPoolExecutor.shutDown();
    }
}

4、運行結果

線程Thread-0正在處理任務!
線程Thread-2正在處理任務!
線程Thread-0正在處理任務!
線程Thread-1正在處理任務!
線程Thread-2正在處理任務!
線程Thread-2正在處理任務!
線程Thread-1正在處理任務!
線程Thread-2正在處理任務!
線程Thread-0正在處理任務!
Thread-1 interrupt
Thread-0 interrupt
Thread-2 interrupt

當第十個任務待處理時,整個線程池已經被shutDown,整個流程結束。

簡單實現java線程池