zoukankan      html  css  js  c++  java
  • 自己定义开发线程池

    首先要明白线程池的作用,根本作用是维持一定的线程数去执行任务(也会是run方法) 弄明白这一点我们就可以写一个简易的线程池了 

    首先定义自己的线程池接口 ;

    package com.MyThread.Mytest;
    
    import java.util.List;
    
    
    public interface MyIThreadPool {
    //执行任务 在执行任务时请确保任务添加完毕;
    public void execute();
    
    //添加批量任务
    public void addTask(List<Runnable> tasks);
    
    public void addTask(Runnable task);
    
    public void addTask(Runnable[] tasks);

    //中途添加任务 当线程池开启时可以用该方法添加一般不介意使用
    // 个人觉得线程池可以根据线程大小 维护 多个任务队列
    //每个线程池取模 到对应任务队列中获取;当人本线程中没有提供此实现

    public void addSafeTask(List<Runnable> tasks);
    //销毁线程池 建议使用 销毁前会等待任务完成
    public void destory();
    
    //暴露销毁 不建议使用 可能任务没完成就直接退出
    public void froceDestory();
    
    }
    //接着已经开头提到的思想写出自己的简易线程池 ,具体代码如下
    
    package com.MyThread.Mytest;
    
    import java.util.LinkedList;
    import java.util.List;
    
    public class MyIThreadPoolImp implements MyIThreadPool {
    //任务队列
    private List<Runnable> taskqueue = new LinkedList<Runnable>();
    //默认开启线程数量
    private static final int defaultNums = 5;
    private int threadNums;
    //需设置为volatile型,当赋值变化时线程能感知
    private volatile boolean isRunning = true;
    //线程数 不会变 不需要维持线程安全
    Thread[] taskThreads;
    
    private MyIThreadPoolImp() {
    this(5);
    }
    
    private MyIThreadPoolImp(int num) {
    if (num <= 0) {
    threadNums = defaultNums;
    } else {
    threadNums = num;
    }
    taskThreads = new Thread[threadNums];
    for (int i = 0; i < threadNums; i++) {
    Thread thread = new TaskThread();
    thread.setName("TaskThread--" + i);
    taskThreads[i] = thread;
    }
    
    }
    
    public static MyIThreadPool getMyIThreadPool(int num) {
    return new MyIThreadPoolImp(num);
    }
    
    @Override
    public void addSafeTask(List<Runnable> tasks) {
    synchronized (taskqueue) {
    taskqueue.addAll(tasks);
    }
    
    }
    
    //执行任务
    @Override
    public void execute() {
    for (int i = 0; i < threadNums; i++) {
    System.out.println(taskThreads[i].getName()+"开启啦");
    taskThreads[i].start();
    
    }
    }
    
    @Override
    public void addTask(Runnable[] tasks) {
    for (Runnable task : tasks) {
    taskqueue.add(task);
    }
    }
    
    @Override
    public void addTask(Runnable task) {
    taskqueue.add(task);
    }
    
    //批量添加任务
    @Override
    public void addTask(List<Runnable> tasks) {
    taskqueue.addAll(tasks);
    
    }
    
    @Override
    public void destory() {
    while (!taskqueue.isEmpty()) {
    try {
    Thread.sleep(20);
    } catch (Exception e) {
    System.out.println("请等待任务完成");
    e.printStackTrace();
    }
    }
    isRunning = false;
    for (int i = 0; i < threadNums; i++) {
    taskThreads[i] = null;
    }
    
    
    }
    
    
    @Override
    public void froceDestory() {
    isRunning = false;
    for (int i = 0; i < threadNums; i++) {
    taskThreads[i].destroy();
    }
    
    
    }
    
    class TaskThread extends Thread {
    
    Runnable runnable = null;
    
    @Override
    public void run() {
    //当线程池可用 无限循环
    while (isRunning) {
    synchronized (taskqueue) {
    if (!taskqueue.isEmpty() && isRunning) {
    runnable = taskqueue.remove(0);
    } else {
    try {
    //等待20后释放锁锁
    taskqueue.wait(20);
    } catch (Exception e) {
    e.printStackTrace();
    ;
    }
    }
    }
    //记住将runnable置于同步代码块外,否则会导致一个线程占有锁时间过长
    if (runnable != null) {
    runnable.run();
    }
    
    
    }
    }
    
    }
    }
    
    
    //接下来进行测试
    package com.MyThread.Mytest;
    
    public class MyThreadPoolTest {
    
    public static void main(String[] args){
    MyIThreadPool myIThreadPool = MyIThreadPoolImp.getMyIThreadPool(7);
    for(int i =0 ;i<50;i++){
    myIThreadPool.addTask(new MyTask());
    }
    myIThreadPool.execute();
    myIThreadPool.destory();
    
     
    
    }
    
    static class MyTask implements Runnable{
    
    @Override
    public void run() {
    System.out.println(Thread.currentThread().getName()+"处理了");
    }
    }
    
    }

    可以发现我们用7个线程就完成了我们50个任务;当然这只是简单的线程池实现 没有涉及到复杂的变化,要想更深入的立即还得去看JDK源码
     

  • 相关阅读:
    Web API 强势入门指南
    毫秒必争,前端网页性能最佳实践
    Windbg Extension NetExt 使用指南 【3】 ---- 挖掘你想要的数据 Managed Heap
    Windbg Extension NetExt 使用指南 【2】 ---- NetExt 的基本命令介绍
    Windbg Extension NetExt 使用指南 【1】 ---- NetExt 介绍
    WCF : 修复 Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service 问题
    透过WinDBG的视角看String
    Microsoft Azure Web Sites应用与实践【4】—— Microsoft Azure网站的“后门”
    企业IT管理员IE11升级指南【17】—— F12 开发者工具
    WCF : 如何将NetTcpBinding寄宿在IIS7上
  • 原文地址:https://www.cnblogs.com/sishahu/p/11067883.html
Copyright © 2011-2022 走看看