- 其次就是我们线程池中线程执行的run方法,执行我们的具体任务!(拿到任务,用于具体执行)
到这,我们手写线程池的东西都理清了代码如下
package com.pool;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/*
- 手写线程池ThreadPool
*/
public class TestPool {
public static void main(String[] args) {
//创建线程池对象
ThreadPool threadPool = new ThreadPool(2, 1000, TimeUnit.MILLISECONDS, 10);
//模拟提供5个任务放给线程池,然而我们线程池设置2个核心线程!
for (int i = 0; i < 5; i++) {
int j = i ;
threadPool.execute(()->{
System.out.println(“任务:”+ j);
});
}
}
}
/*
- 线程池
*/
class ThreadPool{
//任务队列
private BlockQueue taskQueue ; //可以讲任务抽象为Runnable(可运行的!)
//县线程集合
private HashSet workers = new HashSet() ;
//核心线程数
private int coreSize ;
//获取任务的超时时间
private long timeout ;
//时间单位
private TimeUnit timeUnit ;
public void execute (Runnable task){
//加锁保障workers的线程安全
synchronized (workers){
//如果我们的任务数 < coreSize , 直接创建空闲线程,执行!
if (workers.size() < coreSize){
Worker worker = new Worker(task);
System.out.println(“新增worker :” + worker);
worker.start(); //线程执行执行任务
workers.add(worker) ;
} else { //如果我们的任务数 > coreSize , 直接加入任务队列
taskQueue.put(task);
System.out.println(“加入任务队列 :” + task);
}
}
}
public ThreadPool(int coreSize, long timeout, TimeUnit timeUnit,int queueCapacity) {
this.coreSize = coreSize;
this.timeout = timeout;
this.timeUnit = timeUnit;
this.taskQueue = new BlockQueue<>(queueCapacity);
}
//将线程池中的线程包装为一个work类
class Worker extends Thread{
private Runnable task ;
public Worker(Runnable task) {
this.task = task;
}
@Override //执行任务
public void run() {
//task不为空,直接执行任务
//当task不为空任务队列有任务执行,队列中的任务
// while(task != null || (task = taskQueue.take()) != null) //死等,线程池中的线程一直等待获取任务队列中的任务
while(task != null || (task = taskQueue.poll(timeout,timeUnit)) != null){ //等一会儿任务队列没有就不等了,停止线程,下次啥时候来,啥时候再新建
try{
System.out.println(“正在运行任务:” + task);
task.run();
}catch (Exception e){
e.printStackTrace();
}finally {
task = null ;
}
}
synchronized (workers){
System.out.println(“线程执行任务结束,移处线程池 :” + this);
workers.remove(this) ;
}
}
}
}
/*
- 阻塞队列
*/
class BlockQueue{
//1、任务队列
private Deque queue = new ArrayDeque<>() ;
//2、锁 : 用于锁住对头元素,防止其被多个线程同时获取!
private ReentrantLock lock = new ReentrantLock() ;
//3、生产者条件变量 (1) 任务队列满了,任务(生产者)就会进入WaitSet
private Condition fullWaitSet = lock.newCondition() ;
//4、消费者条件变量 (2) 任务队列为空,线程池中的线程(消费者)进WaitSet
private Condition emptyWaitSet = lock.newCondition() ;
//5、容量
private int capacity ;
public BlockQueue(int capacity) {
this.capacity = capacity;
}
//增强我们线程获取当前队列中的任务的方法,如果队列为空,进入休息室等待(带时限的,不会死等)
public T poll(long timeout , TimeUnit unit){
lock.lock();
try{
long nanos = unit.toNanos(timeout) ; //超时时间统一转换为纳秒
while(queue.isEmpty()){ //队列为空,线程池中的线程去等待
try {
if(nanos <= 0) return null ; //如果nanos <= 0 说明超时限了,直接唤醒
nanos = emptyWaitSet.awaitNanos(nanos); //如果被提前唤醒,返回nanos的剩余时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T task = queue.removeFirst();//队列不为空,获取并且移除队头任务
fullWaitSet.signal(); //有空闲线程,唤醒正在休息的任务
return task ; //返回取到的任务
}
finally {
lock.unlock();
}
}
//线程(消费者)获取任务队列当中的任务
public T take(){
lock.lock();
try{
while(queue.isEmpty()){ //队列为空,线程池中的线程去等待
try {
emptyWaitSet.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T task = queue.removeFirst();//队列不为空,获取并且移除队头任务
fullWaitSet.signal(); //有空闲线程,唤醒正在休息的任务
return task ;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/dec0ff38707f1796329d45044f28e81e.jpeg)
最后
我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习
已经将知识体系整理好(源码,笔记,PPT,学习视频)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
om: 33%;" />
最后
我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习
已经将知识体系整理好(源码,笔记,PPT,学习视频)
[外链图片转存中…(img-SAKjN1MO-1713695220503)]
[外链图片转存中…(img-2zPzCwnt-1713695220504)]
[外链图片转存中…(img-RjOi5D8z-1713695220504)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!