Java并發(fā)之并行程序基礎

實戰(zhàn)Java高并發(fā)程序設計筆記


有關線程你必須知道的事

  1. 進程
    • 進程(Process)是計算機中程序關于某數(shù)據(jù)集合上的一次運行活動,事系統(tǒng)進行資源分配和調(diào)度的基本單位腮鞍,是操作系統(tǒng)結(jié)構的基礎弛房。
  2. 線程的幾個狀態(tài)
  • 首先看Thread中的一個枚舉State道盏,線程共有六個狀態(tài),每個狀態(tài)的含義注釋講的已經(jīng)很清楚了
/**
     * A representation of a thread's state. A given thread may only be in one
     * state at a time.
     */
    public enum State {
        /**
         * The thread has been created, but has never been started.
         */
        NEW,
        /**
         * The thread may be run.
         */
        RUNNABLE,
        /**
         * The thread is blocked and waiting for a lock.
         */
        BLOCKED,
        /**
         * The thread is waiting.
         */
        WAITING,
        /**
         * The thread is waiting for a specified amount of time.
         */
        TIMED_WAITING,
        /**
         * The thread has been terminated.
         */
        TERMINATED
    }
  • 各狀態(tài)間的關系如下圖

    線程狀態(tài)圖
  1. Thread的start( )方法和run( )方法的區(qū)別

    • run( )方法是一個普通的方法文捶,調(diào)用該方法會在當前線程中串行執(zhí)行run( )中的代碼
    • start( )是個一個線程安全的方法荷逞,該方法首先會檢查當前線程是否處于New狀態(tài), 然后將其加入到ThreadGroup中粹排,最后調(diào)用Native start0( )方法,在新的線程中串行執(zhí)行run( )中的代碼
  2. 終止線程

  • 調(diào)用Thread.stop( )就會立即線程終止种远,方法太過暴力,可以強行把執(zhí)行到一半的線程終止顽耳,例如如下代碼
public class ThreadStop {
    public static void main(String arg[]) throws InterruptedException {
        Thread mThread = new StopThread() ;
        mThread.start();
        Thread.sleep(100);
        mThread.stop();//調(diào)用stop終止線程可導致run( )方法中的代碼僅執(zhí)行一部分
    }
static class StopThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100000; i++) {
                    System.out.println("i "+ i);
            }
        }
    }
}

可能得到如下結(jié)果坠敷,i的值并不等于99999
i 24956
i 24957
i 24958
i 24959
i 24960
i 24961
i 24962

  1. 線程中斷
  • 線程中斷時一種重要的線程協(xié)作機制妙同。嚴格講,線程中斷并不會使線程立即退出膝迎,而是給線程發(fā)送一個通知粥帚,并告知目標線程,有人希望你退出限次!目標線接到通知后如何處理完全由目標線程自行決定芒涡。
  • 中斷線程(Thread.interrupt( )),通知目標線程中斷,也就是設置中斷標志位
 public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();
        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();  
    }
  • 判斷是否被中斷(Thread.isInterrupted( ))
public boolean isInterrupted() {
        return isInterrupted(false);
    }

    /**
     * Tests if some Thread has been interrupted.  The interrupted state
     * is reset or not based on the value of ClearInterrupted that is
     * passed.
     */
    private native boolean isInterrupted(boolean ClearInterrupted);
  • 判斷是否被中斷并清除當前中斷狀態(tài)
/**
     * Tests whether the current thread has been interrupted.  The
     * <i>interrupted status</i> of the thread is cleared by this method.  In
     * other words, if this method were to be called twice in succession, the
     * second call would return false (unless the current thread were
     * interrupted again, after the first call had cleared its interrupted
     * status and before the second call had examined it).
     *
     * <p>A thread interruption ignored because a thread was not alive
     * at the time of the interrupt will be reflected by this method
     * returning false.
     *
     * @return  <code>true</code> if the current thread has been interrupted;
     *          <code>false</code> otherwise.
     * @see #isInterrupted()
     * @revised 6.0
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }
  • 給出一斷代碼卖漫,顯示線程中斷,注意Thread.sleep( )方法會使當前線程休眠一段時間费尽,若在此時線程接收到中斷信號,sleep會拋出InterruptedException異常羊始,并且會清除中斷標志位依啰。若不做處理,當前線程永遠不會中斷店枣。
public class ThreadInterrupt {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = new InterruptThread();
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
        Thread.sleep(4000);
    }
    static class InterruptThread extends Thread {
        @Override
        public void run() {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("Interrupted");
                    break;
                }
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    System.out.println("Interrupted when sleep");
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
                Thread.yield();//讓出當前CPU,然后跟其他線程競爭CPU的使用權
            }
        }
    }
}
  1. 等待( wait )和通知( notify )
public final native void wait() throws InterruptedException;
public final native void notify();
public final native void notifyAll();
  • wait 會使當前線程停止進入等待隊列而轉(zhuǎn)換為等待狀態(tài)直到其他線程在同一個object調(diào)用notify或notifyAll
  • notify 會從等待隊列中隨機選擇一個線程將喚醒
  • notifyAll 喚醒所有等待隊列中的線程速警,等待線程就會去競爭資源
  • wait 和 sleep 都可以讓線程等待一段時間,除了wait可以被喚醒外鸯两,wait 會釋放目標對象的鎖而sleep不會釋放任何資源
  1. 掛起( suspend ) 和繼續(xù)執(zhí)行( resume )線程
  • suspend會導致線程暫停的同時并不會釋放任何資源闷旧。如果其他任何線程想訪問被他暫用的鎖時都會那不會該所而進入等待狀態(tài)。直到對應線程調(diào)用resume被掛機的線程才能繼續(xù)執(zhí)行钧唐,但是如果resume意外地在suspend前就調(diào)用了忙灼,那么被掛起的線程可能很難有機會繼續(xù)唄執(zhí)行
  1. 等待線程結(jié)束( join ) 和謙讓( yield )
public final void join() throws InterruptedException
public final synchronized void join(long millis)
public static native void yield();
  • join( ) 表示無限等待,它會一直阻塞當前線程钝侠,直到目標線程執(zhí)行完畢
  • oin(long millis) 參數(shù)的意思是等待目標線程的最大時間该园,如果超過時間目標線程還沒有執(zhí)行完畢那么當前線程就會繼續(xù)執(zhí)行下去
  • yield( )一旦調(diào)用,就會使當前線程讓出CPU帅韧,然后可能會跟其他線程競爭CPU資源
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末里初,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子忽舟,更是在濱河造成了極大的恐慌双妨,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叮阅,死亡現(xiàn)場離奇詭異刁品,居然都是意外死亡,警方通過查閱死者的電腦和手機浩姥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門挑随,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人勒叠,你說我怎么就攤上這事兜挨【翰” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵暑劝,是天一觀的道長。 經(jīng)常有香客問我颗搂,道長担猛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任丢氢,我火速辦了婚禮傅联,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疚察。我一直安慰自己蒸走,他們只是感情好,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布貌嫡。 她就那樣靜靜地躺著比驻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪岛抄。 梳的紋絲不亂的頭發(fā)上别惦,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音夫椭,去河邊找鬼掸掸。 笑死,一個胖子當著我的面吹牛蹭秋,可吹牛的內(nèi)容都是我干的扰付。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼仁讨,長吁一口氣:“原來是場噩夢啊……” “哼羽莺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起洞豁,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤禽翼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后族跛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闰挡,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年礁哄,在試婚紗的時候發(fā)現(xiàn)自己被綠了长酗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡桐绒,死狀恐怖夺脾,靈堂內(nèi)的尸體忽然破棺而出之拨,到底是詐尸還是另有隱情,我是刑警寧澤咧叭,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布蚀乔,位于F島的核電站,受9級特大地震影響菲茬,放射性物質(zhì)發(fā)生泄漏吉挣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一婉弹、第九天 我趴在偏房一處隱蔽的房頂上張望睬魂。 院中可真熱鬧,春花似錦镀赌、人聲如沸氯哮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喉钢。三九已至,卻和暖如春良姆,著一層夾襖步出監(jiān)牢的瞬間出牧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工歇盼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舔痕,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓豹缀,卻偏偏與公主長得像伯复,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子邢笙,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

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