java自定义线程池实现
Posted 一乐乐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java自定义线程池实现相关的知识,希望对你有一定的参考价值。
自定义线程池实现
✌ 一、先讲讲思路:我们模拟的是java中的线程池的实现
自定义一个线程池(特点:不断执行任务):
1、有个存放任务容器----------队列(“信息通道”,要能够存、取任务,所以要有存的方法,取的方法),线程池,线程池嘛,任务的执行就是通过线程来执行的。~~~~~需要有固定的活动线程去执行队列的任务。
2,存取任务,并控制线程的状态
存:需要在线程池还存活(没有关闭)时存进去,存完要通知!!!( notify()方法是随机唤醒一个线程 )
取:如果线程池空了,就等待wait()!(让线程等待一下) 然后取出队列的任务!
需要synchronized同步一下!
3,特点:不断执行任务
咱选择的设计模式时:外边添加任务后,咱线程池内部就立马执行咱的任务。所以,在外部,咱只需调用咱线程池的添加任务的方法就够了(为了形象生动,以及装一下B,咱添加任务的方法名称取名为-----runTask() )
接下来就得靠线程内功发力了:在线程池内部,为了实现不断执行任务呢,需要有固定的活动线程去执行队列的任务。
(1)首先咱要明白的是,咱是通过线程来执行任务的,所以咱内部需要不断new线程,然后启动线程。~~~~~~~new线程、启动线程应该写到咱的构造方法里,符合“自动”。
(2)一旦启动,系统会自动调用线程的run() 方法,而咱线程run() 方法里不断的获取任务,执行run() 任务!
(3)由于java内置的Thread类,执行完任务就被销毁了,不符合咱要的不断!so,咱需要在原来的Thread类基础上改装一下它。
二、细节处理分析:
(1)拿点原材料:选择继承ThreadGroup,实现构造方法,传递参数(线程数量),这里的super不能省略哦,因为这个super带参啊。
(2)线程池,有装载线程任务的队列(队列特点-----先进先出!,符合咱添加完任务顺序,与启动添加任务的执行顺序一致性)。
(3)需要有固定的活动线程去执行队列的任务。
(4)线程池特点:任务执行完成后,线程池还要继续工作!,所以我们定义一个变量来控制线程池的工作状态!!!----------- 书写一个不断工作的线程类
(5)取任务、添加任务代码:
三、全部代码:
❀ class CustThreadPool
package CustThreadPool; import java.util.LinkedList; import java.util.Queue; /** * 自定义线程池 * @author Huangyujun * */ public class CustThreadPool extends ThreadGroup{ /** 线程数量*/ private int threadCount; /** 存放任务的线程队列 */ Queue<Runnable> queue = null; public CustThreadPool(String name) { super("当前的线程池最大线程数量" + name); this.threadCount = Integer.parseInt(name); queue = new LinkedList<Runnable>(); //需要有固定的活动线程去执行队列的任务。 for(int i = 0; i < threadCount; i++) { // new custThread(runTask()); //Thread 不太符合咱的设计需求,需要改装一下 new custThread().start(); } } /** * 任务队列添加任务 * @param task */ public synchronized void runTask(Runnable task) { //添加完,通知唤醒线程 if(null != task) { queue.offer(task); } notifyAll(); } /** *取出一个等待执行的任务 * @return */ public synchronized Runnable getTask() { //先判断队列是否为空 while(queue.isEmpty()) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return queue.poll(); } private class custThread extends Thread{ @Override public void run() { //执行取出的任务 while(true) { Runnable task = null; task = getTask(); if(null == task) { break; } task.run(); } } } }
❀class test
package CustThreadPool; /** * 测试类 * @author Huangyujun * */ public class test { public static void main(String[] args) { CustThreadPool custThreadPool = new CustThreadPool("4"); for(int i = 0; i < 4; i++) { Task task = new Task(); // new Thread(task).start(); custThreadPool.runTask(task); } } } class Task implements Runnable{ @Override public void run() { System.out.println("线程"+Thread.currentThread().getName() + "开始执行"); try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("线程"+Thread.currentThread().getName() + "执行完成"); } }
参考自:老九学堂《线上训练营java视频~网络编程~多线程池》
以上是关于java自定义线程池实现的主要内容,如果未能解决你的问题,请参考以下文章