JAVA面試匯總(二)多線程(二)

多線程內(nèi)容比較多悯周,今天寫完了第二篇粒督,后邊應(yīng)該還有三或者四。

1. 同步方法和同步塊禽翼,哪個(gè)是更好的選擇屠橄?

(1)同步方法:即有synchronized關(guān)鍵字修飾的方法。 由于java的每個(gè)對(duì)象都有一個(gè)內(nèi)置鎖闰挡,當(dāng)用此關(guān)鍵字修飾方法時(shí)锐墙, 內(nèi)置鎖會(huì)保護(hù)整個(gè)方法。在調(diào)用該方法前长酗,需要獲得內(nèi)置鎖溪北,否則就處于阻塞狀態(tài)。synchronized關(guān)鍵字也可以修飾靜態(tài)方法夺脾,此時(shí)如果調(diào)用該靜態(tài)方法之拨,將會(huì)鎖住整個(gè)類。
(2)同步塊:即有synchronized關(guān)鍵字修飾的語(yǔ)句塊咧叭。 被該關(guān)鍵字修飾的語(yǔ)句塊會(huì)自動(dòng)被加上內(nèi)置鎖蚀乔,從而實(shí)現(xiàn)同步。
(3)同步是一種高開銷的操作菲茬,因此應(yīng)該盡量減少同步的內(nèi)容吉挣。 通常沒有必要同步整個(gè)方法,使用synchronized代碼塊同步關(guān)鍵代碼即可婉弹。

2. run()和start()方法區(qū)別

(1)run()是實(shí)現(xiàn)Runable接口和繼承Thread必須重寫的睬魂,多線程實(shí)現(xiàn)的主方法,寫的是具體的多線程執(zhí)行的編碼內(nèi)容镀赌。
(2)start()方法是啟動(dòng)執(zhí)行多線程的方法氯哮,表示真正開始運(yùn)行多線程方法。

3. 如何控制某個(gè)方法允許并發(fā)訪問線程的個(gè)數(shù)佩脊?

Semaphore創(chuàng)建時(shí)設(shè)定最多同時(shí)訪問個(gè)數(shù)蛙粘,acquire()申請(qǐng)新請(qǐng)求計(jì)數(shù)+1垫卤,達(dá)到設(shè)定數(shù)值后,內(nèi)部會(huì)執(zhí)行Thread的掛起操作出牧,并把超過指定個(gè)數(shù)的線程放入到隊(duì)列中等待喚醒穴肘。當(dāng)release()后會(huì)喚醒隊(duì)列里的前幾個(gè)線程執(zhí)行。

import java.util.concurrent.Semaphore;
public class SemaphoreTest {
    static Semaphore semaphore = new Semaphore(2, true);
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    test();
                }
            }).start();
        }
    }
    public static void test() {
        try {
            //這塊可以運(yùn)行時(shí)可以看到實(shí)際時(shí)先打印出來舔痕,說明已經(jīng)進(jìn)入了方法了
            System.out.println("waiting"+Thread.currentThread().getName());
            //申請(qǐng)一個(gè)新的請(qǐng)求
            semaphore.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"進(jìn)來了");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"走了");
        //釋放一個(gè)請(qǐng)求
        semaphore.release();
    }
}

4. 在Java中wait和seelp方法的不同评抚;

(1)wait()方法,是屬于Object類伯复,wait()出發(fā)后慨代,線程會(huì)放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池啸如,只有針對(duì)此對(duì)象調(diào)用notify()方法后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲取對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)
(2)sleep()方法侍匙,是屬于Thread類的,sleep()方法的執(zhí)行過程中叮雳,線程不會(huì)釋放對(duì)象鎖

5. Thread類中的yield方法有什么作用想暗?

Thread.yield()可以暫停當(dāng)前正在執(zhí)行的線程對(duì)象,讓其他有相同優(yōu)先級(jí)的線程執(zhí)行帘不。它是一個(gè)靜態(tài)方法而且只保證當(dāng)前線程放棄CPU占用而不能保證其它線程一定能占用CPU说莫,執(zhí)行yield()的線程有可能在進(jìn)入到暫停狀態(tài)后馬上又被執(zhí)行。

6. 什么是不可變對(duì)象寞焙,它對(duì)寫并發(fā)應(yīng)用有什么幫助储狭?

對(duì)象一旦被創(chuàng)建它的狀態(tài)(對(duì)象的數(shù)據(jù),也即對(duì)象屬性值)就不能改變捣郊, 例如String辽狈、基本類型的包裝類(Long,Double等)模她、BigInteger和BigDecimal等稻艰。主要是線程安全,在多線程情況下不可改變侈净,天生線程安全尊勿。

7. 談?wù)剋ait/notify關(guān)鍵字的理解

都是繼承自O(shè)bject的方法,wait()方法用來將當(dāng)前線程置入休眠狀態(tài)畜侦,notify()用來通知那些可能等待該對(duì)象的對(duì)象鎖的其他線程元扔。如果有多個(gè)線程等待,則線程規(guī)劃器任意挑選出其中一個(gè)wait()狀態(tài)的線程來發(fā)出通知旋膳,并使它等待獲取該對(duì)象的對(duì)象鎖澎语。

8. 為什么wait, notify 和 notifyAll這些方法不在thread類里面?

簡(jiǎn)單的說,由于wait擅羞,notify和notifyAll都是鎖級(jí)別的操作尸变,所以把他們定義在Object類中,因?yàn)殒i屬于對(duì)象减俏。
那么復(fù)雜的說呢召烂?因?yàn)殒i是在對(duì)象頭中的markWorld的中標(biāo)記的,wait和notify直接理解為get和set方法娃承,實(shí)際上就是對(duì)鎖的操作奏夫,因此理解來說,這個(gè)應(yīng)該放到Object類中历筝,而不是在Thread類中酗昼。

9. 什么導(dǎo)致線程阻塞恬涧?

(1)Thread.sleep方法休眠一段時(shí)間枯跑,線程放棄cpu逗旁,一段時(shí)間后在恢復(fù)運(yùn)行
(2)線程執(zhí)行wait()方法跷叉,進(jìn)入阻塞狀態(tài),直到notify或者notifyAll方法喚醒
(3)等待相關(guān)資源:線程執(zhí)行I/O操作或進(jìn)行遠(yuǎn)程通信時(shí)彪置,會(huì)因?yàn)榈却嚓P(guān)的資源而進(jìn)入阻塞狀態(tài)逞频。例如線程執(zhí)行System.in.read()時(shí),如果用戶沒有輸入惕稻,則一直等待
(4)調(diào)用了yield方法后,同樣會(huì)進(jìn)入阻塞狀態(tài)蝙叛。
(5)suspend() 是讓線程進(jìn)入阻塞狀態(tài)俺祠,沒有resume()是不會(huì)恢復(fù)的。
(6)join()方法借帘,被join的Thread要等待join的Thread執(zhí)行完畢才能繼續(xù)執(zhí)行蜘渣。

10. 講一下java中的同步的方法

(1)當(dāng)多個(gè)線程同時(shí)操作一個(gè)可共享的資源變量時(shí)(如數(shù)據(jù)的增刪改查),將會(huì)導(dǎo)致數(shù)據(jù)不準(zhǔn)確肺然,相互之間產(chǎn)生沖突蔫缸,因此加入同步鎖以避免在該線程沒有完成操作之前,不被其他線程的調(diào)用际起,從而保證了該變量的唯一性和準(zhǔn)確性拾碌。
(2)同步方法有synchronized關(guān)鍵字修飾的方法。由于java的每個(gè)對(duì)象都有一個(gè)內(nèi)置鎖街望,當(dāng)用此關(guān)鍵字修飾方法時(shí)校翔, 內(nèi)置鎖會(huì)保護(hù)整個(gè)方法。在調(diào)用該方法前灾前,需要獲得內(nèi)置鎖防症,否則就處于阻塞狀態(tài)。
(3)synchronized關(guān)鍵字也可以修飾靜態(tài)方法,此時(shí)如果調(diào)用該靜態(tài)方法蔫敲,將會(huì)鎖住整個(gè)類饲嗽。
(4)synchronized代碼塊同步關(guān)鍵代碼
(5)使用特殊域變量(volatile)實(shí)現(xiàn)線程同步,但是不能完全避免同步問題奈嘿,因?yàn)槠洳荒鼙WC原子操作喝噪,它只是在取得該變量值的時(shí)候是從內(nèi)存中讀取的而不是存緩存中讀取。
(6)使用重入鎖實(shí)現(xiàn)線程同步指么,通過lock和unlock來控制方法的執(zhí)行鎖酝惧。
(7)ThreadLocal的方式,由于每個(gè)線程都是獨(dú)立的ThreadLocal伯诬,所以其實(shí)并不存在什么同步晚唇,以及沖突,每個(gè)線程都在自己的空間內(nèi)執(zhí)行盗似。

public class Bank {
    //實(shí)際上這個(gè)是每個(gè)線程獨(dú)立的ThreadLocal哩陕,并不共享,因此多個(gè)線程調(diào)用addMoney
    //或者subMoney的時(shí)候赫舒,都是在自己的獨(dú)立線程內(nèi)的悍及,并不共享,不存在沖突
    private static ThreadLocal<Integer> count = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };
    // 存錢
    public void addMoney(int money) {
        count.set(count.get() + money);
        System.out.println(System.currentTimeMillis() + "存進(jìn):" + money);

    }
    //取錢
    public void subMoney(int money) {
        if (count.get() - money < 0) {
            System.out.println("余額不足");
            return;
        }
        count.set(count.get() - money);
        System.out.println(+System.currentTimeMillis() + "取出:" + money);
    }
    //查詢
    public void lookMoney() {
        System.out.println("賬戶余額:" + count.get());
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末接癌,一起剝皮案震驚了整個(gè)濱河市心赶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缺猛,老刑警劉巖缨叫,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異荔燎,居然都是意外死亡耻姥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門有咨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琐簇,“玉大人,你說我怎么就攤上這事座享⊥裆蹋” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵征讲,是天一觀的道長(zhǎng)据某。 經(jīng)常有香客問我,道長(zhǎng)诗箍,這世上最難降的妖魔是什么癣籽? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任挽唉,我火速辦了婚禮,結(jié)果婚禮上筷狼,老公的妹妹穿的比我還像新娘瓶籽。我一直安慰自己,他們只是感情好埂材,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布塑顺。 她就那樣靜靜地躺著,像睡著了一般俏险。 火紅的嫁衣襯著肌膚如雪严拒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天竖独,我揣著相機(jī)與錄音裤唠,去河邊找鬼。 笑死莹痢,一個(gè)胖子當(dāng)著我的面吹牛种蘸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播竞膳,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼航瞭,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了坦辟?” 一聲冷哼從身側(cè)響起刊侯,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎长窄,沒想到半個(gè)月后滔吠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挠日,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翰舌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嚣潜。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖椅贱,靈堂內(nèi)的尸體忽然破棺而出懂算,到底是詐尸還是另有隱情,我是刑警寧澤庇麦,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布计技,位于F島的核電站,受9級(jí)特大地震影響山橄,放射性物質(zhì)發(fā)生泄漏垮媒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望睡雇。 院中可真熱鬧萌衬,春花似錦、人聲如沸它抱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)观蓄。三九已至混移,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侮穿,已是汗流浹背沫屡。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撮珠,地道東北人沮脖。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像芯急,于是被迫代替她去往敵國(guó)和親勺届。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容