手写一个简单的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(List
tasks); /** * @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 List
taskQueue = 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);        List
taskList = 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:八种基本排序算法的JAVA实现
下一篇:实现一个简单的SpringIoc容器

发表评论

最新留言

初次前来,多多关照!
[***.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
python遇到了‘module‘ object has no attribute ‘socket‘问题,大概率是这个原因 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使用adb logcat时日志中文乱码问题,使用chcp 65001设置编码即可 2021-06-30
Android的.dex、.odex与.oat文件扫盲 2021-06-30