1. 程式人生 > >ThreadPool執行緒池使用及解決主執行緒和子執行緒執行順序問題

ThreadPool執行緒池使用及解決主執行緒和子執行緒執行順序問題

 執行緒池建立五個執行緒,每個執行緒往list中新增100個元素。synchronized只鎖執行緒共享變數list物件,程式碼段內僅新增元素及列印資訊。設定10ms睡眠時間給其餘執行緒機會。

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
        //list是所有執行緒共享變數需要加鎖避免衝突
		final List list = new ArrayList();
		for(int i=0;i<5;i++) {
			fixedThreadPool.execute(new Runnable() {
				@Override
				public void run() {
                    //j是執行緒內部變數,每個執行緒都有一份,自己會管理,不會衝突
					int j=100;
						while(j>0) {
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
							synchronized (list) {
							list.add(j);
							System.out.println(Thread.currentThread().getName()+"---------"+list.size());
						    j--;
						}

					}
				}
			});
		}
		fixedThreadPool.shutdown();
        //這裡的sysout輸出是在main執行緒中的,其list的size根據當時這個list的情況只輸出一次,可能是任意小於500的值
		System.out.println(Thread.currentThread().getName()+"---------"+list.size());

輸出結果:(注意這裡的main-----0  這個值是fixedThreadPool.shutdown();之後的sysout輸出。)包括main執行緒一共有6個執行緒。

main執行緒不執行run內程式碼段,直接往下繼續執行其餘程式碼(如果快的話可能一行執行緒內程式碼都沒執行就執行run外的程式碼了)。

main---------0  pool-1-thread-2---------1 pool-1-thread-3---------2 pool-1-thread-4---------3

....

pool-1-thread-3---------497 pool-1-thread-2---------498 pool-1-thread-4---------499 pool-1-thread-5---------500

關於main執行緒:main執行緒可能在其餘子執行緒執行完就執行到尾了。但是很多生產情況是要獲取子執行緒結果來處理的。此時可以設定等待時間等待子執行緒結束

  1. // 啟動一次順序關閉,執行以前提交的任務,但不接受新任務。

  2. threadPool.shutdown();

  3. //// 設定最長等待5秒

  4. if(!pool.awaitTermination(5, TimeUnit.SECONDS)){

  5. // 超時的時候向執行緒池中所有的執行緒發出中斷(interrupted)。再超時直接強行關閉。

  6. pool.shutdownNow();

  7. }

 或者可以用join()方法

,保證子執行緒執行完才執行主執行緒(這個例子用簡單的new Thread,threadPool可以自己延伸):

  1. // 使用執行緒安全的Vector

  2. Vector<Thread> threads = new Vector<Thread>();

  3. for (int i = 0; i < 10; i++) {     .......  省略建立子執行緒方法

  4. threads.add(iThread);   // 將每一個子執行緒放到集合中,iThread代表某個子執行緒

  5. for (Thread iThread : threads) {     //在主執行緒中迴圈呼叫子執行緒的join()

  6. try {

  7. // 等待所有執行緒執行完畢

  8. iThread.join();

  9. } catch (InterruptedException e) {

  10. e.printStackTrace();

  11. }

  12. }

  13. System.out.println("主線執行。");  //這個sysout會在所有子執行緒完成後執行

關於shutdown:“問題解答完畢後請舉手示意!”是shutdown方法。“老師我做完了!”是各個任務(Runnable)的執行結束。

shutdown只作為通知的作用