JAVA多線程(五)

這張我們講講多線程之間通信和ThreadGroup!

單線程間通信:

如果服務器端有若干個線程會從隊列中獲取想要的數(shù)據(jù)止邮,進行異步處理捌显,那么這些線程是如何知道隊列中有數(shù)據(jù)呢?
1.一個比較笨的方法-不斷輪詢国瓮,如果隊列中有數(shù)據(jù),那么讀取數(shù)據(jù)并且處理匠楚,如果沒有 再次等待若干時間巍膘,再次輪詢,
2.第二種方法為:通知機制如果隊列中有數(shù)據(jù)芋簿,則通知現(xiàn)場開始工作峡懈,沒有,則通知線程休息与斤。

初始wait 和Notify

舉個栗子
線程之間進行通信肪康,首先實現(xiàn)一個EventQueue,該Queue有三種狀態(tài)撩穿,
1.隊列滿了磷支,最多可容乃多少個Event
2.隊列空,當所有的Event都被處理食寡,沒有在提交Event的時候.
3.有Event但是沒有滿雾狈,有新的Event被提交,但此時沒有上線抵皱。

public class EventQueue {

    private final int max ;

    static class Event{}

    private final LinkedList<Event> eventQueue = new LinkedList<>();

    private final  static int DEFAULT_MAX_EVENT = 200;

    public EventQueue(){
        this(DEFAULT_MAX_EVENT);
    }

    public EventQueue(int max){
        this.max = max;
    }

    private void console(String msg){
        System.out.printf("%s :%s \n",Thread.currentThread().getName(),msg);
    }

    public void put(Event event){
        synchronized(eventQueue){
            while(eventQueue.size() >= max){
                  console("隊里滿了!");
                try {
                    eventQueue.wait();
                    System.out.println("我在wait 方法后面");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            console("事件被提交!");
            eventQueue.addLast(event);
            eventQueue.notifyAll();
        }
    }


    public Event take(){
        synchronized(eventQueue){
            while (eventQueue.isEmpty()){
                try {
                    console("當前隊列為空!");
                    eventQueue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            Event event = eventQueue.removeFirst();
            this.eventQueue.notifyAll();

            console("這個事件被處理:"+event);
            return event;
        }
    }

}

put(Event event);將當前event添加到LinkList的鏈表中善榛,take();從LinkList拿到頭部的Event辩蛋。
wait和notify方法詳解
wait()方法有三個重載方法。

  public final void wait() throws InterruptedException
  public final void wait(long timeout) throws InterruptedException
  public final void wait(long timeout,int nanos)throws InterruptedException

wait方法的三個重載方法都調用wait(long timeout);這個方法移盆,Object的wait(long timeout)方法會導致當前線程進入阻塞悼院,直到有其他線程調用了Object的notify或者notifyAll方法,或者wait到了一定的時間而自動喚醒。
wait方法必須擁有該對象的Monitor咒循,也就是wait方法必須在同步方法中使用据途。
當前線程執(zhí)行了該對象的wait方法之后,將會放棄該montor的所有權并且進入與對象關聯(lián)的wait set中叙甸,
notify 喚醒正在執(zhí)行該對象wait方法颖医,被喚醒的對象需要重新獲取對該對象所關聯(lián)monitor的lock才能繼續(xù)執(zhí)行。

關于wait和notify的注意事項

1.wait是可中斷的方法蚁署,其他線程是可以調用interrupt是可以將其打斷的便脊。
2.如果線程執(zhí)行了wait方法 ,會加入與之對應的wait set
3.當線程進入wait set之后光戈,notify方法可以進行喚醒,也就是從wait set中彈出來遂赠。
4.必須在同步代碼塊中使用wait 和notify
5.同步代碼的monitor必須與執(zhí)行wait 和notify的方法的對象一致久妆。也就是說那個對象進行同步,就只能用哪個對象進行wait和notify操作跷睦。

wait和sleep的區(qū)別

1.wait和sleep 都會使線程進入阻塞狀態(tài)筷弦。都是可以中斷的,中斷后收到中斷異常
2.wait是Object的方法抑诸,sleep是Thread特有的方法
3.wait必須要在同步代碼塊中使用烂琴,而sleep不需要
4.同步代碼塊中,執(zhí)行sleep方法時蜕乡,并不會釋放monitor的鎖奸绷,而wait方法會釋放。
5.sleep方法如果指定休眠時間层玲,休眠時間到了之后會主動退出阻塞号醉,而wait方法(沒有指定修改時間)則需要被其他線程中斷后才能退出阻塞。

wait set介紹

在虛擬機規(guī)范中存在一個線程休息室(wait set) 的概念辛块,wait set是什么樣的數(shù)據(jù)結構 官方并沒有給出規(guī)范畔派,但是不管怎么樣,當一個線程執(zhí)行了wait方法后润绵,都會進入到與改對象monitor關聯(lián)的wait set中线椰,并且釋放monitor的所有權,一個線程調用該monitor的notify方法之后尘盼,其中一個線程會彈出來憨愉,至于是先進先出烦绳,還是隨機 JVM并沒有 給出規(guī)范。而執(zhí)行notifyAll 則不需要考慮那個線程會被彈出莱衩,因為wait set中的所有wait線程都將被彈出爵嗅。


notify方法只會喚醒一個線程
notifyAll方法會喚醒所有的線程

synchronized關鍵字的缺陷

1.synchronized提供了一種排它機制,某個線程獲取monitor可能會被阻塞笨蚁,而這種阻塞有兩個很明顯的缺陷睹晒,第一,無法控制阻塞時長括细,第二伪很,阻塞不可被中斷。

ThreadGroup 與Thread 介紹

在JAVA程序中奋单,默認情況下锉试,新的線程都會被加入到Main線程所在的group中,main線程的group名字同線程名览濒,如同父子關系一樣,ThreadGroup同樣也存在父子關系呆盖,當創(chuàng)建一個線程的時候,當前線程都會被加入到一個ThreadGroup中贷笛,


Thread和ThreadGroup關系圖
創(chuàng)建ThreadGroup
public ThreadGroup(String name)
public ThradGroup(ThreadGroup parent,String name)

方法一:指定了Thread的名字应又,但是該ThreadGroup的父ThreadGroup是創(chuàng)建它的線程所在的ThreadGroup;
方法二:ThreadGroup的構造函數(shù)賦予group名字的同時顯示地指定了父group。

ThreadGroup的基本操作

-activeCount() 用于獲取group中活躍的線程乏苦。這是個預估值株扛,并不能保證100%準確,
-activeGroupCount() 用于獲取group中活躍的字group汇荐,這也是個預估值洞就。
-getName用于獲取group的名字
-getParent()用于獲取group的父group,如果父group不存在掀淘,則會返回null旬蟋。比如System的group就為Null
-list() 該方法沒有返回值,執(zhí)行該方法會將group中所有的活躍線程信息全部輸出到控制臺繁疤,
-setMaxPriority(int priority)指定group的最大優(yōu)先級咖为,最大優(yōu)先級不能超過父group的最大優(yōu)先級,執(zhí)行方法不僅會改變當前group的最大優(yōu)先級稠腊,還會改變子group的最大優(yōu)先級
-interrupt()一個ThreadGroup調用interrupt會導致group中所有active線程都被interrupt,也就是該group中的每一個線程的interrupt標識都被設置了躁染,
-destory() 用于銷毀ThreadGroup,該方法只是針對一個沒有任何active線程的group進行destory標記架忌,調用改方法的直接結果是在父group中將自己移除吞彤。
-daemon(),ThreadGroup也可以調用setDaemon方法,將當前ThreadGroup設置為守護ThreadGroup,如果一個ThradGroup設置為守護ThradGroup,如果該group中沒有任何一個active線程的時候饰恕,該group將自動destory挠羔。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市埋嵌,隨后出現(xiàn)的幾起案子破加,更是在濱河造成了極大的恐慌,老刑警劉巖雹嗦,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件范舀,死亡現(xiàn)場離奇詭異,居然都是意外死亡了罪,警方通過查閱死者的電腦和手機锭环,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泊藕,“玉大人辅辩,你說我怎么就攤上這事⊥拊玻” “怎么了玫锋?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長讼呢。 經常有香客問我景醇,道長,這世上最難降的妖魔是什么吝岭? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮吧寺,結果婚禮上窜管,老公的妹妹穿的比我還像新娘。我一直安慰自己稚机,他們只是感情好幕帆,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赖条,像睡著了一般失乾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纬乍,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天碱茁,我揣著相機與錄音,去河邊找鬼仿贬。 笑死纽竣,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播蜓氨,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼聋袋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了穴吹?” 一聲冷哼從身側響起幽勒,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎港令,沒想到半個月后啥容,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡缠借,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年干毅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泼返。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡硝逢,死狀恐怖,靈堂內的尸體忽然破棺而出绅喉,到底是詐尸還是另有隱情渠鸽,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布柴罐,位于F島的核電站徽缚,受9級特大地震影響,放射性物質發(fā)生泄漏革屠。R本人自食惡果不足惜凿试,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望似芝。 院中可真熱鬧那婉,春花似錦、人聲如沸党瓮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寞奸。三九已至呛谜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間枪萄,已是汗流浹背隐岛。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留呻引,地道東北人礼仗。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親元践。 傳聞我的和親對象是個殘疾皇子韭脊,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容