• 简单的自定义线程池(java)


    package threadpool_test;
    
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingDeque;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 自定义一个简单的线程池
     * 
     * ***/
    public class ThreadPool {
    
        private static final int coreThreadNum=3;//核心线程数
        private static final int maxThreadNum=8;//最大线程数
        
        private boolean working=true;//打开、关闭线程池
        private BlockingQueue<Thread> workThreads=new LinkedBlockingDeque<>(maxThreadNum);//当前工作线程
        
        private BlockingQueue<Runnable> tasks=new LinkedBlockingDeque<>(10);//任务队列
        
        public void execute(Runnable task) throws InterruptedException{
            if(task==null) throw new NullPointerException();
            int workNum=workThreads.size();
            if(workNum<coreThreadNum ){//当前工作线程少于核心线程数,立即启动一个线程进行工作
                Worker worker=new Worker(task);
                Thread thread=new Thread(worker);
                workThreads.offer(thread);//特殊值,add会抛出异常
                thread.start();
            }
            else if(tasks.size()<10){//任务池还没满,就把任务放进任务池里
                tasks.offer(task);
            }
            else if(workNum<maxThreadNum && tasks.size()==10){//任务队列满,开启多余线程来完成任务
                Worker worker=new Worker();
                Thread thread=new Thread(worker);
                System.out.println("开启新线程了"+thread.getName());
                workThreads.offer(thread);
                thread.start();
            }
            else{
                    System.out.println("放弃该任务");
                    return;
            }
        }
        
        public void shutDown(){
            this.working=false;
            for(Thread worker:workThreads){
                System.out.println("终止线程名:"+worker.getName());
                worker.interrupt();
            }
            System.out.println("终止线程池线程");
            Thread.currentThread().interrupt();
        }
        
        private class Worker implements Runnable{//任务包装类
            private Runnable task_origal;
            public Worker() {
            }
            public Worker(Runnable task) {
                this.task_origal=task;
            }
                @Override
                public void run() {
                    if(task_origal!=null)
                        task_origal.run();
                    while(working){
                        try {
                            Runnable task=tasks.take();//阻塞提取任务,阻塞状态下的中断并不会真的中断
                            task.run();
                        } catch (InterruptedException e) {
                            System.out.println("真的终止了");
                            Thread.currentThread().interrupt();
                        }
                    }
                }
                
            }
    }
    package threadpool_test;
    
    import java.util.concurrent.TimeUnit;
    /**
     * 测试类
     * **/
    public class testMain {
    public static void main(String[] args) throws InterruptedException {
        ThreadPool pool=new ThreadPool();
        for(int i=0;i<20;i++){
            pool.execute(new Task("任务"+i));
        }
        TimeUnit.SECONDS.sleep(4);
        pool.shutDown();
    }
    }

    显示结果:

    当前运行线程名:Thread-0当前任务名为:任务0
    当前运行线程名:Thread-2当前任务名为:任务2
    当前运行线程名:Thread-2当前任务名为:任务4
    当前运行线程名:Thread-2当前任务名为:任务5
    当前运行线程名:Thread-2当前任务名为:任务6
    当前运行线程名:Thread-2当前任务名为:任务7
    当前运行线程名:Thread-2当前任务名为:任务8
    当前运行线程名:Thread-2当前任务名为:任务9
    当前运行线程名:Thread-2当前任务名为:任务10
    当前运行线程名:Thread-2当前任务名为:任务11
    当前运行线程名:Thread-2当前任务名为:任务12
    开启新线程了Thread-3
    当前运行线程名:Thread-1当前任务名为:任务1
    当前运行线程名:Thread-1当前任务名为:任务14
    当前运行线程名:Thread-3当前任务名为:任务15
    当前运行线程名:Thread-3当前任务名为:任务16
    当前运行线程名:Thread-3当前任务名为:任务17
    当前运行线程名:Thread-3当前任务名为:任务18
    当前运行线程名:Thread-3当前任务名为:任务19
    当前运行线程名:Thread-0当前任务名为:任务3
    终止线程名:Thread-0
    真的终止了
    终止线程名:Thread-1
    终止线程名:Thread-2
    真的终止了
    真的终止了
    终止线程名:Thread-3
    终止线程池线程
    真的终止了

    ps:该线程池功能非常之简单,仅为了加深线程池核心原理而做。里面关于任务队列满后的处理情况,在这里直接简单的使用放弃该任务的方法;

  • 相关阅读:
    浅涉OPC Client
    枚举目标机器已注册的OPC服务器
    C++ DCOM服务器和C#客户端互操作完全解释
    COMException:没有注册类别(REGDB_E_CLASSNOTREG)
    网络化广播主机ZABKZ/AXT8182
    OPC 技术文档之 IOPCBrowseServerAddressSpace 的使用
    SQL Server 2008 r2 服务无法启动
    Infinova V2040 系列 大型矩阵切换/控制系统
    COM中GUID和UUID、CLSID、IID
    django 视图与网址
  • 原文地址:https://www.cnblogs.com/jkavor/p/7234965.html
Copyright © 2020-2023  润新知