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 使用較多的知識的一個概括介紹。