Java核心篇之多线程---day1
Java面試之多線程—day1
一. 線程中sleep方法與wait方法有什么區別?
對于 sleep()方法,我們首先要知道該方法是屬于 Thread 類中的。而 wait()方法,則是屬于Object 類中的。
在調用 sleep()方法的過程中, 線程不會釋放對象鎖。而當調用 wait()方法的時候,線程會放棄對象鎖,進入與該對象相關的等待池中,只有針對此對象當等待時間到了的時候,或者調用 notify()方法后才會返回對象鎖。
二. Java中線程的實現方式?同步的方式?
(繼承thread類,實現runnable接口,通過callable和future來實現(call方法有返回值和聲明異常),使用線程池例如executor框架來實現)
三. 同步鎖與死鎖
同步鎖:當多個線程同時訪問同一個數據時,很容易出現問題。為了避免這種情況出現,我們要保證線程
同步互斥,就是指并發執行的多個線程,在同一時間內只允許一個線程訪問共享數據。 Java 中可
以使用 synchronized 關鍵字來取得一個對象的同步鎖。
死鎖:何為死鎖,就是多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放。
線程池的原理:
線程池做的工作主要是控制運行的線程的數量,處理過程中將任務放入隊列,然后在線程創建后
啟動這些任務,如果線程數量超過了最大數量超出數量的線程排隊等候,等其它線程執行完畢,
再從隊列中取出任務來執行。 他的主要特點為: 線程復用; 控制最大并發數; 管理線程。
線程池的組成:
一個線程池主要有四個方面組成:
1. 線程池管理器:用于創建并管理線程池
2. 工作線程:線程池中的線程
3. 任務接口:每個任務必須實現的接口,用于工作線程調度其運行
4. 任務隊列:用于存放待處理的任務,提供一種緩沖機制
少時間內會被銷毀。**
4. unit: keepAliveTime 的單位。
5. workQueue:任務隊列,被提交但尚未被執行的任務。
6. threadFactory:線程工廠,用于創建線程,一般用默認的即可。
7. handler:拒絕策略,當任務太多來不及處理,如何拒絕任務。
線程池中的線程已經用完了,無法繼續為新任務服務,同時,等待隊列也已經排滿了,再也
塞不下新任務了。這時候我們就需要拒絕策略機制合理的處理這個問題。
JDK 內置的拒絕策略如下:
1. AbortPolicy : 直接拋出異常,阻止系統正常運行。
2. CallerRunsPolicy : 只要線程池未關閉,該策略直接在調用者線程中,運行當前被丟棄的
任務。顯然這樣做不會真的丟棄任務,但是,任務提交線程的性能極有可能會急劇下降。
3. DiscardOldestPolicy : 丟棄最老的一個請求,也就是即將被執行的一個任務,并嘗試再
次提交當前任務。
4. DiscardPolicy : 該策略默默地丟棄無法處理的任務,不予任何處理。如果允許任務丟
失,這是最好的一種方案。
以上內置拒絕策略均實現了 RejectedExecutionHandler 接口,若以上策略仍無法滿足實際
需要,完全可以自己擴展 RejectedExecutionHandler 接口。
6. Java線程池的工作原理:
1. 線程池剛創建時,里面沒有一個線程。任務隊列是作為參數傳進來的。不過,就算隊列里面
有任務,線程池也不會馬上執行它們。
2. 當調用 execute() 方法添加一個任務時,線程池會做如下判斷:
a) 如果正在運行的線程數量小于 corePoolSize,那么馬上創建線程運行這個任務;
b) 如果正在運行的線程數量大于或等于 corePoolSize,那么將這個任務放入隊列;
c) 如果這時候隊列滿了,而且正在運行的線程數量小于 maximumPoolSize,那么還是要
創建非核心線程立刻運行這個任務;
d) 如果隊列滿了,而且正在運行的線程數量大于或等于 maximumPoolSize,那么線程池
會拋出異常 RejectExecutionException。
3. 當一個線程完成任務時,它會從隊列中取下一個任務來執行。
4. 當一個線程無事可做,超過一定的時間( keepAliveTime)時,線程池會判斷,如果當前運
行的線程數大于 corePoolSize,那么這個線程就被停掉。所以線程池的所有任務完成后,它
最終會收縮到 corePoolSize 的大小。
線程與進程的區別:
線程的生命周期(狀態)
1. 新建(new):當程序使用 new 關鍵字創建了一個線程之后,該線程就處于新建狀態,此時僅由 JVM 為其分配
內存,并初始化其成員變量的值.
2. 就緒(runnable):當線程對象調用了 start()方法之后,該線程處于就緒狀態。 Java 虛擬機會為其創建方法調用棧和
程序計數器,等待調度運行。
3. 運行(running):如果處于就緒狀態的線程獲得了 CPU,開始執行 run()方法的線程執行體,則該線程處于運行狀
態
4. 阻塞(blocked):阻塞狀態是指線程因為某種原因放棄了 cpu 使用權,也即讓出了 cpu timeslice,暫時停止運行。
直到線程進入阻塞(runnable)狀態,才有機會再次獲得 cpu timeslice 轉到運行(running)狀
態。阻塞的情況分三種:
5. 死亡(dead):線程會以下面三種方式結束,結束后就是死亡狀態。
start方法和run方法的區別:
1)。 調用start方法來啟動多線程,這時候蔡真正的實現多線程運行,這時無需等待run方法執行完畢就可以直接繼續執行下面的代碼,這個時候線程是處于就緒(runnable) 狀態。
2)。run方法稱為線程體,調用run方法的時候,線程進入運行態,當run方法執行完畢時,線程就結束了。
守護線程
守護線程也叫“服務線程”,為用戶提供公共服務,在沒有用戶可提供的時候會自動離開。守護線程的優先級比較低。
垃圾回收線程就是一個經典的守護線程,當我們程序中不在有其他任何運行的線程時,程序就不會產生垃圾,垃圾回收器也就無事可做,垃圾回收器就會自動離開。
總結
以上是生活随笔為你收集整理的Java核心篇之多线程---day1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UP装机部署步骤大纲
- 下一篇: java美元兑换,(Java实现) 美元