• 线程池


    public interface Task{
        public void perform()throws Exception;
        }
    import java.lang.Thread;
    
    public class MyTask implements Task{
        private int taskId = 0;
        
        public MyTask(int taskId){
            this.taskId = taskId;
            }
            
        public void perform(){
            System.out.println("MyTask["+ this.taskId +"] start");
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
                e.printStackTrace();
                }
            System.out.println("MyTask["+ this.taskId +"] end");
            }
        }
    import java.lang.ThreadGroup;
    import java.util.LinkedList;
    import java.lang.Thread;
    import java.lang.IllegalThreadStateException;
    import java.lang.InterruptedException;
    
    public class MyThreadPool extends ThreadGroup{
        private  static int threadPoolId ;        //线程池编号
        private int poolThreadId ;            //线程池中线程编号
        private boolean isAlive ;                //线程池是否为激活状态
        private LinkedList taskQueue ;        //任务列表,列表的长度是自增式的,任务数由入参时给出并生成任务
        
        public MyThreadPool(int threadNumbers){
            super("MyThreadPool-" + (threadPoolId++));
            //将父类设置为守护线程,线程池中的所有线程被销毁时,该线程池也会自动销毁
            super.setDaemon(true);
            this.isAlive = true ;
            this.taskQueue = new LinkedList();
            for(int i=0;i<threadNumbers;i++){
                (new PoolThread()).start();
                }
            }
            
        @SuppressWarnings("unchecked")    
        public synchronized void addTask(Task task){
            //如果线程池不运行则无需添加任务
            if(!this.isAlive){
                throw new IllegalThreadStateException();
                }
            if(task!=null){
                this.taskQueue.add(task);
                System.out.println("[addTask]当前线程["+Thread.currentThread()+"] "+"当前任务队列任务数["+this.taskQueue.size()+"]");
                this.notify();        //添加一个任务则唤醒一个等待任务的线程
                }
            }
            
        private synchronized Task getTask() throws InterruptedException{
            //如果任务列表为空,线程被唤醒了,则需要进行循环,如果是while用if代替则不会循环执行
            while(taskQueue.size()==0){
                if(!this.isAlive){
                    return null;
                    }
                System.out.println("任务队列没有任务了"+"[getTask]当前线程["+Thread.currentThread()+"] 等待");
                this.wait();
                }
            System.out.println("[getTask]当前线程["+Thread.currentThread()+"] "+"当前任务队列任务数["+this.taskQueue.size()+"]");
            return (Task)this.taskQueue.removeFirst();
            }
            
        public void close(){
            synchronized (this){
                if(this.isAlive){
                //不再添加任务和取任务
                this.isAlive = false;
                //移除列表中所有任务
                this.taskQueue.clear();
                System.out.println("清空任务队列后任务数["+this.taskQueue.size()+"]");
                //中断当前线程组
                this.interrupt();
                    }
                }
            }    
            
        public void join(){
            synchronized (this){
                //不再添加任务和取任务
                this.isAlive = false;
                //通知多所有等待该Feild的线程
                this.notifyAll();
                }
            //等待运行的线程执行完已经获取的任务后一起停止
            //创建一个线程数组,数组长度为当前线程池活跃线程数
            Thread[] threads = new Thread[this.activeCount()];
            //将线程池中活动的线程拷贝到线程数组中
            int count = this.enumerate(threads);
            for(int i=0;i<count;i++){
                try{
                        threads[i].join();
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
                }
            System.out.println("当前任务队列任务数["+this.taskQueue.size()+"]");
            }
            
        //线程仅组成线程池,所以线程池中的线程类一般作为线程池的内部类    
        class PoolThread extends Thread{
            public PoolThread(){
                System.out.println("PoolThread["+this+"]");
                }
                
            public void run(){
                //线程池被中断时,线程池中的所有线程都被中断了,如果线程未中断,则一直循环执行while中的语句
                while(!this.isInterrupted()){
                    Task task = null;
                    try{
                            //每200毫秒获取一个任务
                            task = getTask();
                            Thread.sleep(300);
                    }catch(InterruptedException e){
                        e.printStackTrace();
                        }
                    if(task==null){
                        return;
                        }
                    try{
                        task.perform();
                    }catch(Throwable e){
                        uncaughtException(this,e);
                        }
                    }
                }
            }
        }
    public class ThreadPoolTest{
        public static void main(String[] args){
            MyThreadPool threadPool = new MyThreadPool(3);
            int taskCount = 10;
            for(int i=0;i<taskCount;i++){
                threadPool.addTask(new MyTask(i));
                //每100毫秒生成一个任务
                try{
                    Thread.sleep(100);
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
                }
                //执行完for循环语句后,然后立即执行main中for后面的语句
            threadPool.close();
            
    //        threadPool.join();
            }
        }

    执行threadPool.close();结果:

    G:maul keyboard hread hreadpool>java ThreadPoolTest
    PoolThread[Thread[Thread-0,5,main]]
    PoolThread[Thread[Thread-1,5,main]]
    任务队列没有任务了[getTask]当前线程[Thread[Thread-0,5,main]] 等待
    PoolThread[Thread[Thread-2,5,main]]
    任务队列没有任务了[getTask]当前线程[Thread[Thread-1,5,main]] 等待
    任务队列没有任务了[getTask]当前线程[Thread[Thread-2,5,main]] 等待
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[1]
    [getTask]当前线程[Thread[Thread-0,5,main]] 当前任务队列任务数[1]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[1]
    [getTask]当前线程[Thread[Thread-1,5,main]] 当前任务队列任务数[1]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[1]
    [getTask]当前线程[Thread[Thread-2,5,main]] 当前任务队列任务数[1]
    MyTask[0] start
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[1]
    MyTask[1] start
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[2]
    MyTask[2] start
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[3]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[4]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[5]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[6]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[7]
    清空任务队列后任务数[0]
    MyTask[0] end
    MyTask[1] end
    MyTask[2] end

    G:maul keyboard hread hreadpool>

    执行threadPool.join();结果:

    G:maul keyboard hread hreadpool>java ThreadPoolTest
    PoolThread[Thread[Thread-0,5,main]]
    PoolThread[Thread[Thread-1,5,main]]
    任务队列没有任务了[getTask]当前线程[Thread[Thread-0,5,main]] 等待
    PoolThread[Thread[Thread-2,5,main]]
    任务队列没有任务了[getTask]当前线程[Thread[Thread-1,5,main]] 等待
    任务队列没有任务了[getTask]当前线程[Thread[Thread-2,5,main]] 等待
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[1]
    [getTask]当前线程[Thread[Thread-0,5,main]] 当前任务队列任务数[1]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[1]
    [getTask]当前线程[Thread[Thread-1,5,main]] 当前任务队列任务数[1]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[1]
    [getTask]当前线程[Thread[Thread-2,5,main]] 当前任务队列任务数[1]
    MyTask[0] start
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[1]
    MyTask[1] start
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[2]
    MyTask[2] start
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[3]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[4]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[5]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[6]
    [addTask]当前线程[Thread[main,5,main]] 当前任务队列任务数[7]
    当前任务队列任务数[7]
    MyTask[0] end
    [getTask]当前线程[Thread[Thread-0,5,main]] 当前任务队列任务数[7]
    MyTask[1] end
    [getTask]当前线程[Thread[Thread-1,5,main]] 当前任务队列任务数[6]
    MyTask[2] end
    [getTask]当前线程[Thread[Thread-2,5,main]] 当前任务队列任务数[5]
    MyTask[3] start
    MyTask[4] start
    MyTask[5] start
    MyTask[3] end
    [getTask]当前线程[Thread[Thread-0,5,main]] 当前任务队列任务数[4]
    MyTask[4] end
    [getTask]当前线程[Thread[Thread-1,5,main]] 当前任务队列任务数[3]
    MyTask[5] end
    [getTask]当前线程[Thread[Thread-2,5,main]] 当前任务队列任务数[2]
    MyTask[6] start
    MyTask[7] start
    MyTask[8] start
    MyTask[6] end
    [getTask]当前线程[Thread[Thread-0,5,main]] 当前任务队列任务数[1]
    MyTask[7] end
    MyTask[8] end
    MyTask[9] start
    MyTask[9] end

    G:maul keyboard hread hreadpool>

  • 相关阅读:
    扩展当easyui datagrid无数据时,显示特定值。如:没有数据
    draggable datagrid columns
    easyui combobox 带 checkbox
    LightOJ1003---Drunk(拓扑排序判环)
    算法分析---回文数推断
    Android集成百度地图SDK
    BS一机双屏的解决方式
    myeclipse中更改web项目在tomcat中部署的路径
    Linux内核调试技术——jprobe使用与实现
    【Servlet】把文件写到Respond输出流里面供用户下载
  • 原文地址:https://www.cnblogs.com/celine/p/9574882.html
Copyright © 2020-2023  润新知