面試題之---java多執行緒
(一)多執行緒
1,概念介紹
一般一個應用至少一個程序,一個執行緒,執行緒是程序的一個實體,是CPU排程和分派的基本單位.
最簡單的比喻多執行緒就像火車的每一節車廂,而程序則是火車。車廂離開火車是無法跑動的,同理火車也不可能只有一節車廂。
在作業系統中,執行緒是最小的排程單元,同時又是一種受限的資源,所以不可能無限制的產生,它的建立和銷燬都是比較耗效能的.
因此,要儘量使用執行緒池,來管理執行緒,避免過多建立和銷燬物件帶來的開銷.
2,執行緒的作用
一般,在預設情況下,一個程序就只有一個執行緒,也就是主執行緒.讓進行互動操作.為了使用者操作的流暢性,就不能在主執行緒進行一些耗時操作,比如網路請求,I/O操作,這個時間一長,就容易造成ANR現象.
所以這個時候.就要開啟子執行緒,進行耗時操作,最後通過Handler,AsyncTask,Rxjava等非同步類將結果傳遞到主執行緒,進行UI更新.
3,執行緒的生命週期
新建:執行緒被建立,還沒有呼叫start()
就緒(呼叫start()之後),
執行(執行run()之後),
阻塞(執行緒被暫停),
死亡(執行緒被停止))
(二)執行緒池
1,優點:
A,可以避免不斷的建立和銷燬執行緒帶來的開銷
B,能夠有效的控制執行緒池的最大併發數,避免大量的執行緒之間因互相搶佔系統資源而導致的阻塞現象.
C,能夠提供定時執行和間隔迴圈執行等功能.
2,ThreadPoolExcutor的構造方法中的6個重要引數:
A,CorePoolSize,執行緒池的最大核心執行緒數量.預設情況下,會一直存活.除非設定allowCoreThreadTimeOut屬性為true,那隻要超過KeepAliveTime設定的閒置時長,也會被回收.
B,maximumPoolSize,執行緒池能夠容納的最大執行緒數,當活動執行緒達到這個資料,後續的新任務就不會執行
C,keppAliveTime,非核心執行緒的閒置時長.如果非核心執行緒的閒置時間超過這個時長,就會被回收.
但,allowCoreThreadTimeOut屬性被設定為true,只要超過KeepAliveTime設定的閒置時長,核心執行緒也會被回收.
D,unit,keepAliveTime閒置時長的單位.這是一個列舉,常用的有TimeUnit.MILLISECOND(毫秒),TimeUnit.SECOND(秒),TimeUnit.MINUTES(分鐘)等.
E,workQueue,執行緒池中的任務佇列,通過執行緒池的execute()方法提交的Runnable物件會儲存在這個引數中.
F,threadfactory,為執行緒池提供建立新執行緒的功能.它是一個介面,只有一個抽象方法, Thread newThread(Runnnable r);
3,ThreadPoolExecutor執行順序:
A,當活動的核心執行緒數量未達到設定的核心執行緒數量時,就會直接啟動一個核心執行緒來執行任務
B,當活動的核心執行緒數量達到設定的核心執行緒數量時,就會讓任務到任務佇列中排隊.
C,在步驟B中,若任務佇列排滿了以後,就會立即啟動一個非核心執行緒來執行任務.
D,如果執行緒數量達到執行緒池規定的最大值時,那就會拒絕執行此任務.ThreadPoolExecutor就會呼叫RejectedExecutorHandler的rejectedExecutor()方法來通知呼叫者.
E,當任務執行完,就會一個一個的回收非核心執行緒.核心執行緒不會自動回收,即使閒置,也會存在,除非自己將allowCoreThreadTimeOut屬性設為true.
4,執行緒池的分類:
FixedThreadPool,CacheThreadPool,ScheduledThreadPool,SingleThreadPool,
A,FixedThreadPool,
執行緒數量固定,
只有核心執行緒,且不會被回收,能快速響應外界請求
當所有執行緒在活動時,新任務會處於等待狀態
對列沒有大小限制
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);fixedThreadPool.execute(myRun);
B,CacheThreadPool,
執行緒數量不定,
只有非核心執行緒,最大數量為Integer.MAX_VALUE
閒置時間超過60秒,就會被回收
適合執行大量的耗時少的任務
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();cachedThreadPool.execute(myRun);
C,ScheduledThreadPool
核心執行緒數量固定,非核心執行緒數量不固定
非核心執行緒一旦閒置,就會被回收
主要用於執行定時任務,具有固定週期的重複任務
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);//1秒後執行RunnablescheduledThreadPool.schedule(myRun,1000, TimeUnit.MILLISECONDS);//延遲20毫秒後,每個2秒就執行一次RunnablescheduledThreadPool.scheduleAtFixedRate(myRun,20,2000,TimeUnit.MILLISECONDS);
D,SingleThreadPool
只有一個核心執行緒
將外界任務統一到一個執行緒,這樣任務之間就不需要處理執行緒同步的問題
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();singleThreadExecutor.execute(myRun);