線程通信
推薦文章
通信方式
- 共享對象
- wait notify 和 notifyAll機制 (併發包中的Condition)
注意點
- 不要在字符串常量或全局對象中調用wait(),因爲可能調用notify或notifyAll的時候
不知道喚醒了哪一個,或者爲什麼都喚醒了?因爲多個引用指向的是同一個對象! - 丟失信號:如果一個線程先於被通知線程調用wait()前調用了notify(),等待的線程將錯過這個信號。
可以通過將信號保存在信號類,就是通過一個變量來記錄這個信號,如果notify , 置爲true , wait –> false;
Synchronized
synchronized真的是一個見過n遍的關鍵字,可以說只要提到多線程就會想到它;
可是,
什麼時候要考慮同步?
多個線程對同一個(注意是同一個)資源進行操作(修改),這樣就構成了一種競爭,
這時我們就必須保證線程A對資源的修改對線程B是可見的,也就是說,線程B不會一會
讀到這個數據,一會這個數據就變了.
典型的就是生產者和消費者,它們的共享資源就是存放物品的籃子,生產者往裏面放,消費者
往裏面拿,這時,我們要做就是對籃子的操作進行同步!使同一個時刻只有一個線程具有籃子的使用
權限!
所以,一句話總結:同一個時刻,只有一個線程具有共享資源的鎖;怎麼用它?
比如:線程A , B ; 共享對象 S非靜態方法
- 在方法上加鎖
如果線程A不退出加鎖方法的話,線程B只要調用S中的同步方法就會被阻塞(非同步方法可以調用)
因爲S的鎖被A佔用着,B也想或得S的鎖 ;
- synchronized(object) 代碼塊
這種方法線程獲得就是你放入的Object的鎖,比如 Object= this,那麼它鎖住的就是當前調用的對象!
這種方法粒度更小,只會同步代碼塊,方法的其他部分任意線程都可以同時訪問,退出代碼塊也就會釋放鎖
- synchronized(object) 代碼塊
- 在方法上加鎖
靜態方法
同樣也是兩種方式,但是它所不同的時,調用靜態方法,你鎖住的就是整個類對象 S.class;