java手写线程池,完善中
package com.test001.threadpool; import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; public class ThreadPool <T>{
private int maxRunThreadNum;
private int maxWaitTaskNum;
private int minActiveThreadNum;
private int addTaskTimeout;
private Vector<Worker> workerList;
private static ThreadPool threadPool;
private LinkedBlockingQueue<Task<T>> taskBlockingDeque;
private AtomicLong workingNum = new AtomicLong();
//初始化参数
private ThreadPool(){
maxRunThreadNum = 10;
maxWaitTaskNum = 50;
minActiveThreadNum = 5;
addTaskTimeout = 5;
workerList = new Vector<>(maxRunThreadNum);
taskBlockingDeque = new LinkedBlockingQueue<>(maxWaitTaskNum);
createWorker(minActiveThreadNum); } public synchronized static <T> ThreadPool<T> getThreadPool(){
if(threadPool==null){
threadPool = new ThreadPool<T>();
}
return threadPool;
} public synchronized void close(){
for (Worker worker:workerList){
worker.close();
worker.interrupt();
}
}
// 添加线程
private synchronized boolean createWorker(int num){
if(workerList.size()+num<maxRunThreadNum){
for (int i=0;i<num;i++) {
Worker worker = new Worker();
workerList.add(worker);
worker.start();
}
return true;
}
return false;
} public Future<T> addTask(Callable<T> callable) throws Exception {
// TODO::考虑 计算当前启动的worker和最大worker之间的数量 以及当前正在运行的和启动的数量,启动更多worker
System.out.println("add");
Task<T> task = new Task<>(callable);
boolean flag = taskBlockingDeque.offer(task,addTaskTimeout, TimeUnit.SECONDS);
if(!flag) return null;
return task.getFuture();
} class Task<T>{
public Callable<T> getCallable() {
return callable;
} public void setCallable(Callable<T> callable) {
this.callable = callable;
} public Future<T> getFuture() {
return future;
} public void setFuture(Future<T> future) {
this.future = future;
} private Callable<T> callable;
private Future<T> future; public Task(Callable<T> callable){
this.callable = callable;
this.future = new Future<>();
} } class Worker extends Thread{
private boolean closeFlag = false;
@Override
public void run() {
while(!closeFlag){
if(taskBlockingDeque.isEmpty()){
// TODO::新增信号量,等待唤醒
}else{
Task<T> task = taskBlockingDeque.poll();
if(task!=null){
Callable<T> callable = task.getCallable();
Future<T> future = task.getFuture();
try {
workingNum.getAndDecrement();
T t = callable.call();
// System.out.println("get t="+t);
future.set(t);
workingNum.decrementAndGet();
} catch (Exception e) {
e.printStackTrace();
}
} }
}
} public void close(){
closeFlag = true;
}
} public static void main(String[] args) throws Exception {
long startTime = System.currentTimeMillis(); //获取开始时间 ThreadPool<Integer> t = ThreadPool.getThreadPool();
List<Future<Integer>> futures = new LinkedList<>();
for (int i=1;i<=50;i++){
Integer data = i;
Future<Integer> f = t.addTask(()->{
Random rd = new Random();
// int num = rd.nextInt(5)+1;
int num = data;
// System.out.println("start\tdata="+data+"\t thread="+Thread.currentThread().getName()+"\tsleep:"+num);
Thread.sleep(num*1000);
System.out.println("end\tdata="+data+"\tthread="+Thread.currentThread().getName());
return num;
});
futures.add(f);
}
// Thread.sleep(25*1000);
int i =0;
for(Future<Integer> f :futures){
i++;
System.out.println("get data\t"+i+"="+f.get());
}
t.close();
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
} } class Future<T>{
private volatile boolean hasResp = false;
private T t;
private Semaphore semaphore = new Semaphore(1);
public Future(){
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
} public T get() throws InterruptedException {
// 等待对应的信号量,然后到对应任务编号,取出对应的值
semaphore.acquire();
return t;
} protected void set(T t){
this.t = t;
semaphore.release();
} }
java手写线程池,完善中的更多相关文章
- 手写线程池,对照学习ThreadPoolExecutor线程池实现原理!
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...
- Java实现终止线程池中正在运行的定时任务
源于开发 最近项目中遇到了一个新的需求,就是实现一个可以动态添加定时任务的功能.说到这里,有人可能会说简单啊,使用quartz就好了,简单粗暴.然而quartz框架太重了,小项目根本不好操作啊.当然, ...
- Go组件学习——手写连接池并没有那么简单
1.背景 前段时间在看gorm,发现gorm是复用database/sql的连接池. 于是翻了下database/sql的数据库连接池的代码实现,看完代码,好像也不是很复杂,但是总觉得理解不够深刻,于 ...
- Java多线程和线程池
转自:http://blog.csdn.net/u013142781/article/details/51387749 1.为什么要使用线程池 在Java中,如果每个请求到达就创建一个新线程,开销是相 ...
- Java实现的 线程池
由于最近开始学习java,用到了线程池,按照之前c++的写法写出此java版的线程池 TaskRunnale实现相关任务的接口,具体要实现什么任务在相应的run函数中实现. package threa ...
- java并发包&线程池原理分析&锁的深度化
java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的, ...
- 线程池是什么?Java四种线程池的使用介绍
使用线程池的好处有很多,比如节省系统资源的开销,节省创建和销毁线程的时间等,当我们需要处理的任务较多时,就可以使用线程池,可能还有很多用户不知道Java线程池如何使用?下面小编给大家分享Java四种线 ...
- Java 多线程:线程池
Java 多线程:线程池 作者:Grey 原文地址: 博客园:Java 多线程:线程池 CSDN:Java 多线程:线程池 工作原理 线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: ...
- 自己动手写线程池——向JDK线程池进发
自己动手写线程池--向JDK线程池进发 前言 在前面的文章自己动手写乞丐版线程池中,我们写了一个非常简单的线程池实现,这个只是一个非常简单的实现,在本篇文章当中我们将要实现一个和JDK内部实现的线程池 ...
随机推荐
- 51nod--1185 威佐夫游戏 V2 (博弈, 乘法模拟)
题目: 1185 威佐夫游戏 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆中取任意个或从2堆中 ...
- (转)Vue种key的作用
https://blog.csdn.net/qq_41861679/article/details/80659278 https://cn.vuejs.org/v2/api/#key 其实不只是vue ...
- Python学习笔记六
Python课堂笔记六 常用模块已经可以在单位实际项目中使用,可以实现运维自动化.无需手工备份文件,数据库,拷贝,压缩. 常用模块 time模块 time.time time.localtime ti ...
- CAP分布式事务 学习及简单demo
完全参考 github的指导 demo地址, Pub使用 efcore , Sub 使用 dapper, mysql数据库 https://files.cnblogs.com/files/xtxtx/ ...
- Angular路由——路由基础
一.路由相关对象 Router和RouterLink作用一样,都是导航.Router是在Controller中用的,RouterLink是在模版中用到. 二.路由对象的位置 1.Routes对象 配置 ...
- JS对象与原型链
每个函数都存在一个prototype的属性,然后这个属性值为一个对象,我们称之为原型对象 每个对象都存在着一个隐藏的属性"__proto__" 这个属性引用了创建这个对象的函数的p ...
- 《C和指针》---指针
内存和地址 计算机的内存由许多的位(bit)组成,每个位可以容纳值0或1. 由于一个位所能表示的范围太有限,所以通常许多位合成一组作为一个单元. 这些位置的每一个都被称为字节(byte),每个字节包含 ...
- 【C#】多数组间的取重取余
string[] arrRate = new string[] { "a", "b", "c", "d" };//A s ...
- Linux中Hadoop的环境搭建
一:下载安装 Hadoop 1.1:下载指定的Hadoop 1.2:通过XFTP把文件上传到master电脑bigData目录下 1.3:解压hadoop压缩文件 tar -xvf hadoop-2. ...
- Python编程中出现ImportError: bad magic number in 'numpy': b'\x03\xf3\r\n'
在终端输入ls -a 会出现一个.pyc的文件,将文件删掉