并发程序—线程池

来源:互联网 发布:中建西南院待遇知乎 编辑:程序博客网 时间:2024/05/02 00:26
一.JDK线程池
1.jdk的线程池由ThreadPoolExecutor()演化而来
public ThreadPoolExecutor(int corePoolSize,                //线程池的线程数量                                      int maximumPoolSize,            //线程池的最大线程数量                          long keepAliveTime,            //超过corePoolSize的空闲线程,回在多长时间后销毁                          TimeUnit unit,                //keepAliveTime的时间单位                          BlockingQueue<Runnable> workQueue)        //已提交单尚未执行的任务                          ThreadFactory threadFactory,                //创建线程的工厂,默认即可                          RejectedExecutionHandler handler)         //拒绝策略

  new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
  ExecutorService es = Executors.newCachedThreadPool();
  new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
  es = Executors.newFixedThreadPool(10);
  new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>())
  es = Executors.newSingleThreadExecutor();

2.workQueue的分类
1)直接提交队列:SynchronizedQueue
    当线程数到了corePoolSize,在后来的任务就会提交到workqueue,而该实现的队列只要有插入操作,就会立即执行提交操作,让线程池新建线程执行任务
    若此时线程个数超过maximumPoolSize,就会执行决绝策略,所以通常用该任务队列的线程池,要设置很大的maxPoolSize
2)有界任务队列:ArrayBlockingQueue
    public ArrayBlockingQueue(int capacityu)
    该队列的创建有容量上线,当线程数到达coolPoolSize,任务会加到该队列中,队列满时,新增线程到maxPoolSize,若大于maxPoolSize,执行决绝策略
3)无界队列:LinkedBlockingQueue
    无界队列的线程池当线程数大于corePoolSize后,任务一脸表的形式加入到队列中,知道内存耗尽
4)优先任务队列:priorityBlockingQueue
    该队列中的任务会根据任务的优先级选择执行,他是无界队列
[注]:newFixedThreadPool()的线程数固定,所以corePoolSize和maxPoolSize相等,采用无界队列,让其在系统频繁增加爱任务的时候,会导致内存泄漏
      newCachedThreadPool()也采用无界队列实现,他的corePoolSize为0,说明初始时没有线程,空闲的线程会在60s后回收

3.RefusedExecutionHandler的分类
1)AbortPolicy:直接抛出异常
2)CallerRunsPolicy:在调用这的线程中执行多出的任务
3)DiscardOldestPolicy:丢弃最老的任务请求,(即将处理的任务),尝试提交当前任务
4)DiscardPolicy:丢弃外发处理的任务

[注]:拒绝策略实现的接口:

interface RejectExecutionHandler{    void rejectExecution(Runnable r,Thread t)}

自定义线程池可以实现任务执行谦和执行后的操作:

//自定义线程池class MyThreadPoolExecutor extends ThreadPoolExecutor{    public MyThreadPoolExecutor() {        super(100, 200, 0, TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>());    }    @Override    protected void afterExecute(Runnable r, Throwable t) {        System.out.println("end tId:"+Thread.currentThread().getName());        System.out.println("end tName:"+Thread.currentThread().getName());        System.out.println("end poolSize:"+this.getPoolSize()); // 当前线程池中线程的数量    }    @Override    protected void beforeExecute(Thread t, Runnable r) {        System.out.println("start tId:"+t.getId()+" tName:"+t.getName());    }    }
/*Runnable*/class MyRunnable implements Runnable,Comparable<MyRunnable>{    protected int level;        public MyRunnable(int level) {        super();        this.level = level;    }    @Override    public void run() {        try {            Thread.sleep(1010);        } catch (InterruptedException e) {            e.printStackTrace();        }            System.out.println(this.level+"等级");    }    @Override    public int compareTo(MyRunnable o) {        return this.level>o.level ? 0:-1;    }    }
/*调用*/public static void main(String[] args) throws InterruptedException {    ExecutorService es = new MyThreadPoolExecutor();    for(int i=0;i<1000;i++){        es.execute(new MyRunnable(i));    }    /*    95等级        94等级        99等级        100等级  //初始的100个空闲线程一次执行,超过后加入优先队列,执行等级高的线程        999等级        998等级        997等级  */    }


二.简易的线程池

public class MyThreadPool {    private static MyThreadPool instance = null; //线程池的单例模式        private List<MyThread> threadList;    //线程队列,存放的都是挂起的线程    private int count;                    //加入线程数    private boolean shutDown = false;        private MyThreadPool(){        this.threadList = new Vector(5);        this.count = 0;    }    public int getSize(){        return this.threadList.size();    }    public static synchronized MyThreadPool getInstance(){        if(instance == null)            instance = new MyThreadPool();        return instance;    }        public int getCount() {        return count;    }        public synchronized void add(MyThread myThread){        if(!shutDown){            threadList.add(myThread);  //MyThread是一个用不停止的线程,等待接受真实线程        }else{            myThread.stop();        }    }        /* 1.使用空闲的线程接受runnable<span style="white-space:pre"></span>--所谓空闲,就是把线程的处理逻辑写在一个while(true)里,在这个无限循环中,逻辑处理完,就wait(),使之挂起     * 2.若没有空闲线程则创建线程,并开启线程 */    public synchronized void start(Runnable target){        MyThread myThread = null;        if(threadList.size()>0){            int lastIndex = threadList.size()-1;            myThread = threadList.get(lastIndex);            threadList.remove(lastIndex);//runnable的run()执行后会停止对象运行,相应的也要从list中删除MyThread            myThread.setTarget(target);  // 在永不停止的线程中运行目标线程        }else{            count++;            myThread = new MyThread(this, "myThread #"+count, target);            myThread.start();            this.threadList.add(myThread);        }    }        public synchronized void shutDown(){        this.shutDown = true;        for(Thread t:threadList){            t.stop();        }    }}
//用一个永不停止的线程接收目标targetclass MyThread extends Thread{         private MyThreadPool myThreadPool = null;    private Runnable target = null;    private boolean shutDown = false;    private boolean idle = false;  // 线程是否空闲        public MyThread(MyThreadPool myThreadPool,String name,Runnable target) {        super(name);               // 给产生线程加上名字        this.myThreadPool = myThreadPool;        this.target = target;    }        /* 1.永不结束       * 2.执行加入的runnable     * 3.执行完加入线程池队列,挂起继续等待下一个runnable  */    @Override    public void run() {        while(!shutDown){            idle = false;          //线程在运行中            if(target!=null)                this.target.run();            ////Runnable执行结束后,线程空闲,不释放,加入线程池            idle = true;                       try {                synchronized (this) {                    myThreadPool.add(this);                    wait();       //线程挂起,等待其他线程加入                }            } catch (InterruptedException e) {                e.printStackTrace();            }            idle = false;         //runnable加入后,线程换醒后,不在空闲        }    }    public synchronized void setTarget(Runnable target) {        this.target = target;        notifyAll();             //当notify()后,线程被唤醒,且回到wait()的地方, 继续执行下面的代码    }    }/**调用国策后嗯与下方一样*/



[注]:线程池大小:CPU数量×预期的CPU使用率×(1+等待时间与计算时间的比)

0 0