自己定义开发线程池

首先要明白线程池的作用,根本作用是维持一定的线程数去执行任务(也会是run方法) 弄明白这一点我们就可以写一个简易的线程池了 

首先定义自己的线程池接口 ;

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);

 

//中途添加任务 当线程池开启时可以用该方法添加一般不介意使用
// 个人觉得线程池可以根据线程大小 维护 多个任务队列
//每个线程池取模 到对应任务队列中获取;当人本线程中没有提供此实现

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源码
 

posted @ 2019-06-22 10:19  gds111789  阅读(340)  评论(0编辑  收藏  举报