2.1指蚜、同步方法
同步代碼塊:使用synchronized關(guān)鍵字包裹了一塊代碼肛循,讓這塊代碼同步執(zhí)行。就是每次只能一個線程來執(zhí)行柿究。
同步方法:使用synchronized關(guān)鍵字修飾一個方法,這個方法同步執(zhí)行黄选。就是每次只能一個線程來執(zhí)行蝇摸。
- 普通的方法:對象調(diào)用。鎖定的對象办陷,就是this對象貌夕。
- 靜態(tài)的方法:類調(diào)用。鎖定的對象民镜,就是類名.class
同步的原理:利用對象的互斥鎖啡专。
? 每個線程來訪問,只能有一個線程進入執(zhí)行制圈,第一個動作鎖對象(上鎖)们童。來保證其他線程不能進入執(zhí)行。等到該線程結(jié)束這個同步代碼塊或者同步方法鲸鹦,釋放鎖對象(開鎖)慧库,才允許其他的線程來訪問。
線程安全的類:
StringBuffer
Vector
HashTable
Collections馋嗜,集合的工具類
2.2齐板、線程之間的通信
線程之間的通信:wait(),notify()嵌戈,notifyAll()
wait()——>讓線程進入阻塞狀態(tài)覆积,暫停執(zhí)行。一直阻塞
notify()——>喚醒線程熟呛,wait()住的線程宽档,被喚醒。如果多個線程wait()了庵朝,喚醒其中的一個吗冤。
notifyAll()——>喚醒所有又厉。
語法要求:必須在同步中,由同步的鎖對象來調(diào)用椎瘟。否則java.lang.IllegalMonitorStateException異常覆致。
生產(chǎn)者消費者模型:
生產(chǎn)者(線程t1)負責(zé)生產(chǎn)產(chǎn)品,存入容器中(固定容量)肺蔚,消費者(線程t2)從容器中獲取產(chǎn)品消費掉煌妈。
容器:
生產(chǎn)者:持有資源,生產(chǎn)產(chǎn)品宣羊,存入容器中
消費者:持有資源璧诵,消費掉產(chǎn)品。
容器滿了:最多裝8個雞蛋
生產(chǎn)者:持有資源仇冯,暫停執(zhí)行——直到容器還能繼續(xù)裝之宿。
鎖對象.wait()——>會讓線程進入阻塞狀態(tài)。暫停執(zhí)行苛坚。notify()比被,notifyAll()
消費者:持有資源,直接消費泼舱。等缀。
容器空了:最少0個。
生產(chǎn)者:持有資源娇昙,生產(chǎn)项滑,存入。涯贞。
消費者:持有資源,暫停執(zhí)行——直到容器中有產(chǎn)品
鎖對象.wait()——>會讓線程進入阻塞狀態(tài)危喉。暫停執(zhí)行宋渔。notify(),notifyAll()
代碼分析:
1辜限、產(chǎn)品類:Egg()-->id
2皇拣、產(chǎn)生者:線程
cpu執(zhí)行,run()-->生產(chǎn)雞蛋薄嫡,裝入容器
3氧急、消費者:線程
cpu執(zhí)行,run()-->從容器中獲取雞蛋毫深,吃掉(打印吩坝。。)
容器對象:
? Class實現(xiàn)容器
? 數(shù)組: Egg[] arr = new Egg[8];
? 集合:棧哑蔫,后進先出
同步的代碼:
? 鎖的是容器對象:
wait()和sleep()方法的區(qū)別:
- 出處不同:
- sleep()方法是Thread類中定義的钉寝。
- wait()方法是Object類中定義的弧呐。
- 解除阻塞的方式不同
- sleep()是時間到,自己醒嵌纲。
- wait()方法等待被喚醒:notify()俘枫,或者是notifyAll()
- 對鎖資源的釋放情況
- sleep(),不釋放
- wait()逮走,釋放