java预先创建核心线程,【JavaEE】自主实现java线程池的核心部分

首先思考,线程池最基本的目的是什么?

线程存在“创建”、“运行”、“结束(销毁)”的三个过程,形成所谓的“线程生命周期”。

在CS模式的服务器端,服务器在侦听客户端连接时,每侦听到一个客户端连接请求,都将产生一个线程,这个线程负责维护与客户端的持续通信。若存在大量客户端连接服务器的情况,那么,就会存在大量线程的产生。这种情况,由于每一个线程通常存在比较长的时间,因此,情况不是非常严重。

再看RMI框架:在RMI服务器端,也存在每侦听到一个客户端,就需要产生一个线程,完成客户端对特定方法的调用。这个过程本质上只是执行了一个方法,所以,这个线程将很快结束。那么,在大量客户端都存在向服务器端进行RMI请求的情况下,服务器端会存在海量的线程的“创建”、“销毁”动作。

事实上,线程的“创建”是耗时、耗资源的!如果非常频繁地创建、销毁线程,将使得服务器效率降低!

为避免上述情况,考虑一种可能性:

先创建一些线程,当线程运行结束后,并不直接销毁,而是将它们存放到一个“线程池”中;若有新的线程需求,直接从线程池中获取它们,从而避免频繁、耗资源的线程创建和销毁工作。

上述讨论意味着,每创建一个线程,这个线程都一直保持“运行”状态,直到整个线程池被用户终结,才会结束并销毁。控制同时“运行”的线程数量是必须的。

这里存在一个难点:

如何让一个始终保持运行状态的线程,能切换不同的工作内容?

我们可以设置一个接口,实现接口的类不同,那么,工作内容就不同。代码如下:

public interface ITasker {

void beforeTask();

void task();

void afterTask();

}

这个接口定义了三个方法,实现它的类需要一一实现这些方法。

接下来实现我们执行这些方法的类:

public class Woker implements Runnable{

private volatile ITasker tasker;

private volatile boolean goon;

public Woker() {

lock = new Object();

this.goon = false;

}

public Woker(ITasker tasker) {

lock = new Object();

this.tasker = tasker;

this.goon = false;

}

public void setTasker(ITasker tasker) {

this.tasker = tasker;

}

public void startup() {

if (goon == true) {

return ;

}

goon = true;

new Thread(this).start();

}

public void shutdown() {

if (goon == false) {

return ;

}

goon = false;

}

@Override

public void run() {

while (goon) {

if (tasker != null) {

try {

tasker.beforeTask();

tasker.task();

} catch (Exception e) {

e.printStackTrace();

}

tasker.afterTask();

tasker = null;

}

}

}

}

可以看到,这个类实现了run方法,这个线程一旦开启,就是一个死循环,需要shutdown方法来关闭它。

因为,线程池需要通吃管理很多的线程,那么就会有很多的Woker类。这时,我们需要一个总的容器来管理这些Woker类。

但是,我们还需要考虑如下问

题:

1、应该限定“核心线程”数量; 所谓“核心线程”是一直处在待执行状态的线程;

2、当核心线程数量达到极值,后面产生的线程不再进入空线程池;

3、还要控制最大并行线程数量; 若最大并行线程数量达到极值,则,对于用户产生的新的线程需 求,不再立刻满足,而是等待若干时间,再从空线程池中获取可 用线程。

4、对于线程池的结束,应该考虑到正在执行中的线程的“强制结

束”,或者,“等待结束”这两种处理方式。

public class ThreadPool {

private final Queue freeThreadList;

private final List busyThreadList;

public ThreadPool() {

//这里用的是队列,因为队列的特性是先入先出,而且是线程安全的

freeThreadList = new ConcurrentLinkedQueue();

//这里用的是链表,因为我们需要不断的增加或者删除某个节点。

busyThreadList = new LinkedList<>();

//预先建立5个线程

createWorker(5);

}

public boolean stop() {

Worker worker;

if (busyThreadList.isEmpty()) {

while ((worker = freeThreadList.poll()) != null) {

worker.stop();

}

return true;

}

return false;

}

private void createWorker(int count) {

for (int i = 0; i < count; i++) {

Worker worker = new Worker(this);

worker.start();

freeThreadList.add(worker);

}

}

public void setTask(Tasker tasker) {

Worker worker = freeThreadList.poll();

if (worker == null) {

createWorker(3);

worker = freeThreadList.poll();

}

worker.setTasker(tasker);

busyThreadList.add(worker);

}

void workerFree(Worker worker) {

busyThreadList.remove(worker);

//这里的20是自己设定的核心线程池数量,也可以作为一个成员来在外面初始化

if (freeThreadList.size() < 20) {

freeThreadList.offer(worker);

} else {

worker.stop();

}

}

}

有了ThreadPool类,对于执行完一个Woker,要把它放到freeThreadList里面。我们需要对Woker类进行修改,其实很简单,我们可以给Woker类一个成员,然后在ThreadPool类当我们new Woker时,将自己设置进去。在执行完Woker类里面ITasker接口的方法时,我们需要在Woker类里面调用threadPool的workerFree()方法,同时传递自己作为参数。

到这里,我们也就实现了线程池的核心代码。

[JAVA工程师必会知识点之并发编程]1、现在几乎100%的公司面试都必须面试并发编程,尤其是互联网公司,对于并发编程的要求更高,并发编程能力已经成为职场敲门砖。2、现在已经是移动互联和大数据时代,对于应用程序的性能、处理能力、处理时效性要求更高了,传统的串行化编程无法充分利用现有的服务器性能。3、并发编程是几乎所有框架的底层基础,掌握好并发编程更有利于我们学习各种框架。想要让自己的程序执行、接口响应、批处理效率更高,必须使用并发编程。4、并发编程是中高级程序员的标配,是拿高薪的必备条件。 【主讲讲师】尹洪亮Kevin:现任职某互联网公司首席架构师,负责系统架构、项目群管理、产品研发工作。10余年软件行业经验,具有数百个线上项目实战经验。擅长JAVA技术栈、高并发高可用伸缩式微服务架构、DevOps。主导研发的蜂巢微服务架构已经成功支撑数百个微服务稳定运行【推荐你学习这门课的理由:知识体系完整+丰富学习资料】1、 本课程总计122课时,由五大体系组成,目的是让你一次性搞定并发编程。分别是并发编程基础、进阶、精通篇、Disruptor高并发框架、RateLimiter高并发访问限流吗,BAT员工也在学。2、课程附带附带3个项目源码,几百个课程示例,5个高清PDF课件。3、本课程0基础入门,从进程、线程、JVM开始讲起,每一个章节只专注于一个知识点,每个章节均有代码实例。 【课程分为基础篇、进阶篇、高级篇】一、基础篇基础篇从进程与线程、内存、CPU时间片轮训讲起,包含线程的3种创建方法、可视化观察线程、join、sleep、yield、interrupt,Synchronized、重入锁、对象锁、类锁、wait、notify、线程上下文切换、守护线程、阻塞式安全队列等内容。二、进阶篇进阶篇课程涵盖volatied关键字、Actomic类、可见性、原子性、ThreadLocal、Unsafe底层、同步类容器、并发类容器、5种并发队列、COW容器、InheritableThreadLocal源码解析等内容。三、精通篇精通篇课程涵盖JUC下的核心工具类,CountDownLath、CyclicBarrier、Phaser、Semaphore、Exchanger、ReentrantLock、ReentrantReadWriteLock、StampedLock、LockSupport、AQS底层、悲观锁、乐观锁、自旋锁、公平锁、非公平锁、排它锁、共享锁、重入锁、线程池、CachedThreadPool、FixedThreadPool、ScheduledThreadPool、SingleThreadExecutor、自定义线程池、ThreadFactory、线程池切面编程、线程池动态管理等内容,高并发设计模式,Future模式、Master Worker模式、CompletionService、ForkJoin等课程中还包含Disruptor高并发无锁框架讲解:Disruptor支持每秒600万订单处理的恐怖能力。深入到底层原理和开发模式,让你又懂又会用。高并发访问限流讲解:涵盖木桶算法、令牌桶算法、Google RateLimiter限流开发、Apache JMeter压力测试实战。 【学完后我将达到什么水平?】1、 吊打一切并发编程相关的笔试题、面试题。2、 重构自己并发编程的体系知识,不再谈并发色变。3、 精准掌握JAVA各种并发工具类、方法、关键字的原理和使用。4、 轻松上手写出更高效、更优雅的并发程序,在工作中能够提出更多的解决方案。  【面向人群】1、 总感觉并发编程很难、很复杂、不敢学习的人群。2、 准备跳槽、找工作、拿高薪的程序员。3、 希望提高自己的编程能力,开发出更高效、性能更强劲系统的人群。4、 想要快速、系统化、精准掌握并发编程的人群。【课程知识体系图】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值