手写一个简单的JAVA线程池
发布日期:2022-02-09 20:39:11
浏览次数:11
分类:技术文章
本文共 5871 字,大约阅读时间需要 19 分钟。
最近项目中用到了线程池,俗话说的好,了解他才能打败他,于是自己写了一个简单的线程池拿来实验
1、线程接口,定义线程池中的主要的几个方法
import java.util.List;/** * @Author: wuyaohua * @Description: 线程接口 * @Date: Created in 11:33 2018-08-21 */public interface IThreadPool { /** * @Author : wuyaohua * @Date : 2018-08-21 11:34 * @Description : 加入任务 * @Param : [task] * @Return : void */ void execute(Runnable task); /** * @Author : wuyaohua * @Date : 2018-08-21 11:34 * @Description : 加入任务 * @Param : [task] * @Return : void */ void execute(Runnable[] tasks); /** * @Author : wuyaohua * @Date : 2018-08-21 11:34 * @Description : 加入任务 * @Param : [task] * @Return : void */ void execute(Listtasks); /** * @Author : wuyaohua * @Date : 2018-08-21 11:34 * @Description : 销毁线程 * @Param : [task] * @Return : void */ void destroy();}
2、线程池实现类
import java.util.LinkedList;import java.util.List;import java.util.concurrent.atomic.AtomicLong;/** * @Author: wuyaohua * @Description: 线程池实现类 * @Date: Created in 11:35 2018-08-21 */@SuppressWarnings("ALL")public class ThreadPoolImpl implements IThreadPool { /** * 默认开启线程个数 */ static int WORKER_NUMBER = 5; /** * 完成任务线程数 可见性 */ static volatile int sumCount = 0; /** * 任务队列 list非线程安全,可以优化为BlockingQueue */ static ListtaskQueue = new LinkedList (); /** * 线程工作组 */ WorkerThread[] workThreads; /** * 原子性 */ static AtomicLong threadNum = new AtomicLong(); static ThreadPoolImpl threadPool; //构造方法 public ThreadPoolImpl() { this(WORKER_NUMBER); } public ThreadPoolImpl(int workerNum) { ThreadPoolImpl.WORKER_NUMBER = workerNum; //开辟工作线程空间 workThreads = new WorkerThread[WORKER_NUMBER]; //开始创建工作线程 for (int i = 0; i < WORKER_NUMBER; i++) { workThreads[i] = new WorkerThread(); Thread thread = new Thread(workThreads[i], "ThreadPool-worker" + threadNum.incrementAndGet()); System.out.println("初始化线程数" + (i + 1) + "---------当前线程名称:" + thread.getName()); thread.start(); } } @Override public String toString() { return "工作线程数量为" + WORKER_NUMBER + "已完成的任务数" + sumCount + "等待任务数量" + taskQueue.size(); } //获取线程池 public static IThreadPool getThreadPool() { return getThreadPool(WORKER_NUMBER); } public static IThreadPool getThreadPool(int workerNum) { //容错性,如果小于等于0就默认线程数 if (workerNum <= 0) { workerNum = WORKER_NUMBER; } if (threadPool == null) { threadPool = new ThreadPoolImpl(workerNum); } return threadPool; } @Override public void execute(Runnable task) { synchronized (taskQueue) { taskQueue.add(task); taskQueue.notifyAll(); } } @Override public void execute(Runnable[] tasks) { synchronized (taskQueue) { for (Runnable task : tasks) { taskQueue.add(task); } taskQueue.notifyAll(); } } @Override public void execute(List tasks) { synchronized (taskQueue) { for (Runnable task : tasks) { taskQueue.add(task); } taskQueue.notifyAll(); } } @Override public void destroy() { //循环是否还存在任务,如果存在等待20毫秒处理时间 while (!taskQueue.isEmpty()) { try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } //如果任务队列已处理完成,销毁线程,清空任务 for (int i = 0; i < WORKER_NUMBER; i++) { workThreads[i].setWorkerFlag(); workThreads[i] = null; } threadPool = null; taskQueue.clear(); } /** * 创建工作线程池 */ class WorkerThread extends Thread { /** * 用来标识当前线程属于活动可用状态 */ private boolean isRunning = true; @Override public void run() { Runnable runnable = null; //死循环 while (isRunning) { //非线程安全,所以采用同步锁 synchronized (taskQueue) { while (isRunning && taskQueue.isEmpty()) { try { //如果任务队列为空,等待20毫秒 监听任务到达 taskQueue.wait(20); } catch (Exception e) { e.printStackTrace(); } } //任务队列不为空 if (!taskQueue.isEmpty()) { //获取第一个任务 runnable = taskQueue.remove(0); } } if (runnable != null) { runnable.run(); } sumCount++; runnable = null; } } /** * 销毁线程 */ public void setWorkerFlag() { isRunning = false; } }}
3、线程池测试类
import java.util.ArrayList;import java.util.List;/** * @Author: wuyaohua * @Description: 线程池测试类 * @Date: Created in 11:41 2018-08-21 */public class ThreadPoolTest { public static void main(String[] args) { //获取线程池 IThreadPool t = ThreadPoolImpl.getThreadPool(20); ListtaskList = new ArrayList (); for (int i = 0; i < 100; i++) { taskList.add(new Task()); } //执行任务 t.execute(taskList); System.out.println(t); //销毁线程 t.destroy(); System.out.println(t); } static class Task implements Runnable { private static volatile int i = 1; @Override public void run() { System.out.println("当前处理的线程:" + Thread.currentThread().getName() + " 执行任务" + (i++) + " 完成"); } }}
转载地址:https://blog.csdn.net/JohneyWu/article/details/81916840 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2024年04月22日 21时18分08秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Flink在美团的应用与实践听课笔记
2021-06-30
Java多线程的11种创建方式以及纠正网上流传很久的一个谬误
2021-06-30
JDK源码研究Jstack,JMap,threaddump,dumpheap的原理
2021-06-30
Java使用字节码和汇编语言同步分析volatile,synchronized的底层实现
2021-06-30
javac编译原理和javac命令行的使用
2021-06-30
Unity使用UnityWebRequest实现本地日志上传到web服务器
2021-06-30
Unity使用RenderTexture实现裁切3D模型
2021-06-30
美术和程序吵架,原来是资源序列化格式设置不统一
2021-06-30
Unity iOS接SDK,定制UnityAppController
2021-06-30
Unity iOS接SDK前先要了解的知识(Objective-C)
2021-06-30
记一次iOS闪退问题的定位:NSLog闪退
2021-06-30
Unity打开照相机与打开本地相册然后在Unity中显示照片(Android与iOS)
2021-06-30
无需接入SDK即可在Unity中获取经纬度(Android/iOS),告诉我你的坐标
2021-06-30
Unity获取系统信息SystemInfo(CPU、显卡、操作系统等信息)
2021-06-30
Unity中获取物体的尺寸(size)的三种方法
2021-06-30
Unity中的关节组件和绳子效果的实现
2021-06-30
Unity可视化编程插件: Bolt,可以像UE4的蓝图那样啦
2021-06-30
Android的.dex、.odex与.oat文件扫盲
2021-06-30