Java基础点:多线程
程序、進程、線程概念回顧
a) 程序program:一段靜態代碼,靜態對象
b) 進程process:程序執行的一段過程,正在運行的程序,有特定的生命周期
i. 進程作為資源分配的單位,獨立分配不同的內存空間
c) 線程thread:程序內部的一條執行路徑
i. 一個進程有多個線程,則支持多線程
ii. 線程作為調度和執行的單位,每個線程有獨立的運行棧opera stack和程序計數器PC
iii. 線程共享資源
并行和并發
a) 并行:多個cpu同時執行多個任務
b) 并非:一個cpu同時執行多個任務
線程的創建和使用:java.lang.Thread
Thread常用方法
a) Start(): 啟動當前進程,調用當前進程的run()
b) Run(): 通常需要重寫Thread類中的此方法,是線程執行的操作
c) CurrentThread():靜態方法,返回執行當前代碼的線程
d) getName(): 獲取當前進程的名字
e) setName(): 設置名字
i. 給主線程設置名字:在main方法中調用:Thread.currentThread.setName(“”);
f) Yield(): 一旦線程執行次方法,釋放當前cpu執行權
g) Join(): 在線程a中調用線程b的join()方法,線程a進入阻塞狀態,知道b執行完,a才結束阻塞狀態BLOCK
h) Stop(): //不建議使用 強制線程生命周期結束
i) Sleep(long millitime): 靜態方法 讓當前線程“睡眠”指定的millitime毫秒,在指定的millitime毫秒時間內,當前線程是阻塞狀態。
j) isAlive(): 判斷當前線程是否存活
線程創建方法1:
a) 繼承Thread
b) 創建子類繼承thread
c) 重寫thread run()方法
d) 建子類對象,調用start()
線程創建方法2://這個方式比較好,可以繼承自己的父類
a) 實現Runnable接口
b) 創建一個實現了Runnable接口的類
c) 實現類去實現run()方法—Runnable中的抽線方法
d) 創建實現類的對象
e) 將實現類的對象作為參數傳遞到Thread類的構造器中,創建Thread類的對象
兩種線程創建方式的比較
a) 開發中優先選擇實現Runnable方式
i. 實現時候沒有類的單繼承局限性
ii. 更適合處理多個線程共享資源的情況
iii. 兩種方式都需要重寫Run() 方法,將線程要執行的邏輯寫入run()方法中。
線程優先級
a) 等級1-10
i. Max_Priority == 10
ii. MIN_PRIORITY1
iii. NORM_PRIORITY5,默認的優先級
b) 設置方法:
i. getPriority(): 返回線程優先值
ii. setPriority(int newPriority): 改變線程的優先級
c) 線程創建時,繼承父線程的優先級
d) 低優先級只是獲得調度的概率低,并非在高優先級調度完才調度
線程的生命周期
a) 新建:New,調用start()進入就緒
b) 就緒:Ready queue,獲取cpu執行權到執行
c) 阻塞:Block,運行中的sleep()/join()/等待同步鎖wait()/suspend()吊起?和resume搭配使用
d) 運行:running,yield()放棄cpu運行進入就緒
e) 死亡:執行完方法/stop()/異常
線程安全問題
同步代碼塊 解決線程安全問題
a) Synchronized(同步監視器){//需要被同步的代碼}
b) 同步的代碼:操作共享數據的代碼
c) 同步監視器?Lock 鎖
i. 任何一個類的對像都可以作為鎖
ii. 多個線程必須使用同一把鎖
iii. 在實現Runnable創建多線程,可以使用this作為同步監視器
iv. 在繼承Thread類創建多線程,this作為lock有可能出問題(new出多個對象時),可以使用當前類作為lock
d) 局限性:效率低,相當于單進程
同步方法 解決線程安全問題
a) 對于實現Runnable
i. 如果操作共享數據的代碼完整聲明在一個方法中,則可以將方法聲明為同步的
ii. 隱含的同步監視器為this
b) 對于繼承Thread
i. 不可使用上面的方法,因為隱含的同步監視器為this
ii. 將方法聲明為同步且靜態static的。
iii. 隱含的同步監視器為:當前類.class
c) 對于同步方法
i. Static靜態方法:同步監視器是當前類本身
ii. 非靜態方法:同步監視器為this(new出來的對象)
死鎖deadLock
a) 不同線程分別占用對方需要的同步資源,都在等待對方放棄自己需要的同步資源,導致全員阻塞block
b) 解決方法
i. 專門的算法
ii. 減少同步資源的定義
iii. 避免嵌套同步
JDK5.0 Lock接口 解決線程安全問題
a) Util.concurrent.locks.Lock接口是控制多個線程對共享資源進行訪問的工具。
b) Private ReentrantLock lock = new ReentrantLock(boolean fair); //若fair=true,則符合線程先進先出原則,不填則為默認
c) 鎖定:lock.lock() 解鎖:lock.unlock()
d) 與synchronized區別
i. Syn是自動的釋放同步監視器,lock手動的實現啟動同步和鎖定同步
ii. Lock只有代碼塊鎖,syn有方法和代碼塊鎖
iii. 使用Lock,JVM花費較少時間調度線程,性能更好。有更好的擴展性(提供子類)
線程間的通信
a) Wait(), 釋放鎖,線程進入阻塞狀態 等待被喚醒
b) Notify(),喚醒在等待的優先級高的線程,notifyAll()
c) 以上方法只能出現在同步方法和同步代碼塊中(在lock中不能使用這種方法)
d) 以上方法的調用者必須是同步方法或代碼塊中的同步監視器。
e) 以上方法都定義在Object類中
Sleep方法和wait方法的異同
a) 都可以讓當前線程進入阻塞狀態
b) 不同點
i. Sleep在Thread類中,wait定義在Object中
ii. 調用范圍不同:sleep()可以在任何場景調用,wait只能在同步代碼塊中
iii. Sleep不釋放同步監視器,wait會釋放同步監視器
JDK5.0線程創建新方式
線程創建方式一:實現Callable接口
a) 需要借助Future接口
線程創建方式二:使用線程池
a) ExecutorService service = Executors.newFixedThreadPool(10);–10為線程數
i. 執行:service.execute();–適合Runnable service.submit();–適合callable
ii. 關閉線程池:service.shutdown();
b) 提高響應速度:減少創建線程的時間
c) 降低資源損耗:重復利用線程池的線程,無需每次都創建線程。
d) 便于管理:利用ThreadPoolExecutor(這個是線程池創建實際返回的對象)
總結
總結
以上是生活随笔為你收集整理的Java基础点:多线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java基础点:集合
- 下一篇: blockingdeque java_J