1. 程式人生 > >自己動手寫執行緒池

自己動手寫執行緒池

自己動手寫執行緒池

執行緒池 = 有界/無界佇列<Runable> + List<Thread> + 飽和策略

 

alt

 

import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;

public class MyThreadPool {


    private BlockingQueue<Runnable> blockingQueue = null;

    private ArrayList<Thread> allThreads = null;

    private boolean isWorking = true;

    MyThreadPool(int poolSize,int queueSize){
        blockingQueue = new LinkedBlockingQueue(queueSize);
        allThreads = new ArrayList<>(poolSize);
        for(int i = 0 ; i < poolSize; i++){


            Worker thread = new Worker(this);

            allThreads.add(thread);

            thread.start();
        }
    }


    private static class Worker extends Thread{
        MyThreadPool pool;
        Worker(MyThreadPool pool){
            this.pool = pool;
        }

        @Override
        public void run() {
            while (pool.isWorking || pool.blockingQueue.size() > 0) {
                try {
                    Runnable runnable = pool.blockingQueue.take();
                    runnable.run();
                } catch (InterruptedException e) {
                 //   e.printStackTrace();
                }
            }
        }
    }

    public boolean subumit(Runnable runnable) throws InterruptedException {
       return  blockingQueue.offer(runnable);
    }

    /**兩個問題:
     * 1.阻塞在take地方的怎麼把他停掉?InterruptedException
     * 2.保證已經在queue裡面的Runable要執行完成.  pool.blockingQueue.size() > 0
     */
    public void shutDown(){
        isWorking = false;
        for(Thread thread : allThreads){
            thread.interrupt();
        }
    }


    public static void main(String[] argv) throws InterruptedException {

        int threadCount = 100;

        CountDownLatch countDownLatch = new CountDownLatch(threadCount);

        MyThreadPool myThreadPool = new MyThreadPool(5,10);

        for(int i=0 ; i < threadCount; i++){
            boolean isAccept = myThreadPool.subumit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                     //   e.printStackTrace();
                    }
                    System.out.println("thread " + Thread.currentThread().getName() + " run");
                  //  countDownLatch.countDown();
                }
            });
            if(isAccept){
                System.out.println("Thread " + i + "has been Submit");
            }
        }

      //  countDownLatch.await();

        Thread.sleep(100);

        myThreadPool.shutDown();
    }


}

 

執行緒池被請求打滿的原因有兩個,一個是核心執行緒數太少,還有可能是執行緒runnable的任務耗時變長導致處理不過來。

解決方法一個是增大核心執行緒數;二是檢查是否run裡面有可以