本身定義開發線程池

首先要明白線程池的做用,根本做用是維持必定的線程數去執行任務(也會是run方法) 弄明白這一點咱們就能夠寫一個簡易的線程池了 java

首先定義本身的線程池接口 ;安全

package com.MyThread.Mytest;

import java.util.List;


public interface MyIThreadPool {
//執行任務 在執行任務時請確保任務添加完畢;
public void execute();

//添加批量任務
public void addTask(List<Runnable> tasks);

public void addTask(Runnable task);

public void addTask(Runnable[] tasks);

 

//中途添加任務 當線程池開啓時能夠用該方法添加通常不介意使用
// 我的以爲線程池能夠根據線程大小 維護 多個任務隊列
//每一個線程池取模 到對應任務隊列中獲取;當人本線程中沒有提供此實現ide

public void addSafeTask(List<Runnable> tasks);

 

//銷燬線程池 建議使用 銷燬前會等待任務完成
public void destory();

//暴露銷燬 不建議使用 可能任務沒完成就直接退出
public void froceDestory();

}
//接着已經開頭提到的思想寫出本身的簡易線程池 ,具體代碼以下

package com.MyThread.Mytest;

import java.util.LinkedList;
import java.util.List;

public class MyIThreadPoolImp implements MyIThreadPool {
//任務隊列
private List<Runnable> taskqueue = new LinkedList<Runnable>();
//默認開啓線程數量
private static final int defaultNums = 5;
private int threadNums;
//需設置爲volatile型,當賦值變化時線程能感知
private volatile boolean isRunning = true;
//線程數 不會變 不須要維持線程安全
Thread[] taskThreads;

private MyIThreadPoolImp() {
this(5);
}

private MyIThreadPoolImp(int num) {
if (num <= 0) {
threadNums = defaultNums;
} else {
threadNums = num;
}
taskThreads = new Thread[threadNums];
for (int i = 0; i < threadNums; i++) {
Thread thread = new TaskThread();
thread.setName("TaskThread--" + i);
taskThreads[i] = thread;
}

}

public static MyIThreadPool getMyIThreadPool(int num) {
return new MyIThreadPoolImp(num);
}

@Override
public void addSafeTask(List<Runnable> tasks) {
synchronized (taskqueue) {
taskqueue.addAll(tasks);
}

}

//執行任務
@Override
public void execute() {
for (int i = 0; i < threadNums; i++) {
System.out.println(taskThreads[i].getName()+"開啓啦");
taskThreads[i].start();

}
}

@Override
public void addTask(Runnable[] tasks) {
for (Runnable task : tasks) {
taskqueue.add(task);
}
}

@Override
public void addTask(Runnable task) {
taskqueue.add(task);
}

//批量添加任務
@Override
public void addTask(List<Runnable> tasks) {
taskqueue.addAll(tasks);

}

@Override
public void destory() {
while (!taskqueue.isEmpty()) {
try {
Thread.sleep(20);
} catch (Exception e) {
System.out.println("請等待任務完成");
e.printStackTrace();
}
}
isRunning = false;
for (int i = 0; i < threadNums; i++) {
taskThreads[i] = null;
}


}


@Override
public void froceDestory() {
isRunning = false;
for (int i = 0; i < threadNums; i++) {
taskThreads[i].destroy();
}


}

class TaskThread extends Thread {

Runnable runnable = null;

@Override
public void run() {
//當線程池可用 無限循環
while (isRunning) {
synchronized (taskqueue) {
if (!taskqueue.isEmpty() && isRunning) {
runnable = taskqueue.remove(0);
} else {
try {
//等待20後釋放鎖鎖
taskqueue.wait(20);
} catch (Exception e) {
e.printStackTrace();
;
}
}
}
//記住將runnable置於同步代碼塊外,不然會致使一個線程佔有鎖時間過長
if (runnable != null) {
runnable.run();
}


}
}

}
}


//接下來進行測試
package com.MyThread.Mytest;

public class MyThreadPoolTest {

public static void main(String[] args){
MyIThreadPool myIThreadPool = MyIThreadPoolImp.getMyIThreadPool(7);
for(int i =0 ;i<50;i++){
myIThreadPool.addTask(new MyTask());
}
myIThreadPool.execute();
myIThreadPool.destory();

 

}

static class MyTask implements Runnable{

@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"處理了");
}
}

}

 

能夠發現咱們用7個線程就完成了咱們50個任務;固然這只是簡單的線程池實現 沒有涉及到複雜的變化,要想更深刻的當即還得去看JDK源碼
 測試

相關文章
相關標籤/搜索