線程--線程池篇

java 關於線程池的簡單使用及注意點。

先來看下線程池的原理圖吧,來了runnable請求,進行線程的創建,到coresize之後,會進行緩存(workqueue),當緩存已滿,但最大線程數爲到達的時候,會接着創建新的線程執行runnable。當線程執行完某個runnable之後,會從換從中取走,去執行。

當然,如果達到最大線程了,緩存也慢了,還在進行execute申請/或者是已經shutdown了,則會拋出異常,需要在code中進行捕捉或者設置處理策略。

下面是例子,註釋中也囊括了所有的知識點:

注意點:1.如果已經提供的四中線程池方法滿足需求,則儘量使用:(點擊打開鏈接

2.如果不滿足,需要new的,需要注意rejection的處理(4中策略,一種異常捕捉);

3.注意一下不同的queue的區別(ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue)

public class TryExecutor extends Activity {

    private int QueueSize = 10;

    private int mCoreSize;
    private int mMaxSize;
    private int mKeepAliveTime;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        init();

    }

    private void init() {

        mCoreSize = Runtime.getRuntime().availableProcessors();// cpu core count;
        Log.d(TAG, "Current avaliable processor is: "+mCoreSize);
        mMaxSize = 2 * mCoreSize;// max poor size;
        mKeepAliveTime = 10;//alive time;

        //new ThreadPoolExecutor---ArrayBlockingQueue(FIFO)--which you must set queue size.
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(mCoreSize, mMaxSize,
                mKeepAliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue <Runnable>(QueueSize));

        //new ThreadPoolExecutor--LinkedBlockingDeque(link FIFO)--which you can set queue size or not, if not the size is Integer.MAX_VALUE.
//        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(mCoreSize, mMaxSize, mKeepAliveTime, TimeUnit.SECONDS,
//                new LinkedBlockingDeque <Runnable>());//new LinkedBlockingDeque <Runnable>(QueueSize));

        //new ThreadPoolExecutor--SynchronousQueue(NO queue).
//        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(mCoreSize, mMaxSize, mKeepAliveTime, TimeUnit.SECONDS,
//                new SynchronousQueue <Runnable>());


        //Solve the reject error:
        //1. do noting == AbortPolicy:throw exception.
        //2.DiscardPolicy:drop
        //3.DiscardOldestPolicy: drop the oldeset one
        //4.CallerRunsPolicy: the thread who make executor handle. In this activity, it's the main thread.
        //5. new RejectedExecutionHandler to handle exception.
//        threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());

//        threadPoolExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
//            @Override
//            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
//                //TODO:
//            }
//        });

        //four executor for simple use:
        //1.newFixedThreadPool
        /*
        * public static ExecutorService newFixedThreadPool(int nThreads) {
        *        return new ThreadPoolExecutor(nThreads, nThreads,
        *               0L, TimeUnit.MILLISECONDS,
        *               new LinkedBlockingQueue<Runnable>());
        *       }
        */
        //2.newSingleThreadExecutor
        /*
        * public static ExecutorService newSingleThreadExecutor() {
        *        return new ThreadPoolExecutor(1, 1,
        *               0L, TimeUnit.MILLISECONDS,
        *               new LinkedBlockingQueue<Runnable>());
        *       }
        */
        //3.newCachedThreadPool
        /*
        * public static ExecutorService newCachedThreadPool() {
        *        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
        *               60L, TimeUnit.SECONDS,
        *               new SynchronousQueue<Runnable>());
        *       }
        * */
        //4.newScheduledThreadPool
         /*
        * public static ExecutorService ScheduledThreadPoolExecutor(int corePoolSize) {
        *        return new ThreadPoolExecutor(corePoolSize, Integer.MAX_VALUE,
        *               10L, TimeUnit.MILLISECONDS,
        *               new DelayedWorkQueue());
        *       }
        * */
//        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(mCoreSize);
//        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
//        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//        ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(mCoreSize);


        int i = 0;
        while (i++<15) {
            MyTask task = new MyTask(i);
            threadPoolExecutor.execute(task);

//            fixedThreadPool.execute(task);
//            singleThreadExecutor.execute(task);
//            cachedThreadPool.execute(task);
//            scheduledThreadPool.execute(task);

            Log.d(TAG, "current core pool size: "+threadPoolExecutor.getCorePoolSize() +
                    ", completed task count: "+threadPoolExecutor.getCompletedTaskCount() +
                    ", active count: "+threadPoolExecutor.getActiveCount() +
                    ", pool size: "+threadPoolExecutor.getPoolSize() +
                    ", task count: "+threadPoolExecutor.getTaskCount());
        }

        threadPoolExecutor.allowsCoreThreadTimeOut();
        while (threadPoolExecutor.getActiveCount() != 0) {
            Thread.yield();
        }
        threadPoolExecutor.shutdownNow();
        Log.d(TAG, "Shut down!");
    }


    class MyTask implements Runnable {

        private int index;

        public MyTask(int index) {
            this.index = index;
        }

        @Override
        public void run() {
            try {
                Thread.currentThread().sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.d(TAG,"current thread is: "+Thread.currentThread().getName() + ", index: "+index);
        }
    }

}

如果看的懵逼,建議先看一下這篇文章,基礎概念都有比較好講解:點擊打開鏈接

源碼獲取:點擊打開鏈接

https://github.com/shixin398/MultiThreadDemo

其中還有創建線程,停止線程,線程同步方法,同時啓動線程個數的控制,及當前文章的相應code;

對於thread 使用較多的知識的一個概括介紹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章