并發(fā)編程的三大特性

  • 原子性

一個具有原子性的操作要么全部執(zhí)行,要么不執(zhí)行忽舟。具體來說双妨,原子性的操作執(zhí)行到一半,并不會因為CPU線程調(diào)度而被打斷叮阅,這樣的操作就是原子性操作刁品。在Java并發(fā)編程中,synchronized關(guān)鍵字可以保證操作的原子性浩姥。

public class Atomicity {

    //volatile保證有序性和可見性
    static volatile int num = 0;

    //結(jié)果小于100000
    /*public static void incre() {
        num++;
    }*/

    //結(jié)果等于100000
    public synchronized static void incre() {
        //num++ 等于 num=num+1; 這個操作并不是一個原子操作挑随,它會因為線程調(diào)度而被打斷
        //需要家synchronized來保證原子性
        num++;
    }

    public static void main(String[] args) throws InterruptedException {

        Thread[] arrThread = new Thread[10];

        for(int i = 0; i<arrThread.length; i++) {
            arrThread[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int j = 0; j<10000; j++) {
                        incre();
                    }
                }
            });
            arrThread[i].start();
        }

        for(Thread t : arrThread) {
            t.join();//等每個線程執(zhí)行完
        }

        System.out.println("num ="+num);

    }

}
  • 可見性

程序在多線程下,其中一個線程修改線程之間的共享變量的值時勒叠,其它線程是會感知得道的兜挨,并且會把新的共享變量值以極短的時間同步到其它線程中。在Java中眯分,volatile關(guān)鍵字可以保證操作的可見性拌汇。

public class Visibility {

    //結(jié)果是 start -> assign -> complete -> 死循環(huán)
    //static boolean initFlag = false;

    //結(jié)果是 start -> assign -> complete -> end
    //加了volatile關(guān)鍵字使得initFlag變量的更改對其它線程可見
    static volatile boolean initFlag = false;

    public static void main(String[] args) throws InterruptedException {

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("=========start");
                while(!initFlag) {

                }
                System.out.println("=========end");
            }
        }).start();

        Thread.sleep(2000);

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("=========assign");
                initFlag = true;
                System.out.println("=========complete");
            }
        }).start();

    }

}
  • 有序性

程序在多線程下,程序中代碼執(zhí)行的順序是代碼的先后執(zhí)行的弊决。程序代碼不會因為指令重排序(程序為了優(yōu)化執(zhí)行效率從而打亂了代碼的執(zhí)行順序)而打亂噪舀,從而導致程序產(chǎn)生不同的結(jié)果。在Java中同樣飘诗,volatile關(guān)鍵字也可以保證操作的有序性与倡。

import java.util.HashMap;
import java.util.HashSet;

public class Ordering {
    //運行到后面的結(jié)果:[a=0,b=0, a=1,b=0, a=0,b=1]
    //volatile保證了x、y賦值時的先后順序
    static volatile int x = 0, y = 0;

    //運行到后面的結(jié)果:[a=0,b=0, a=1,b=0, a=0,b=1, a=1,b=1]
    //因為指令重排序昆稿,代碼的執(zhí)行順序出現(xiàn)了 2纺座、4操作 在 1、3的前面貌嫡,例如2413,4213
    //static int x = 0, y = 0;

    public static void main(String[] args) throws InterruptedException {

        HashSet<String> hashSet = new HashSet<>();
        HashMap<String,Integer> hashMap = new HashMap<>();

        for (int i = 0; i<1000000; i++) {
            x = 0; y = 0;
            hashMap.clear();
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    int a = x; //1
                    y = 1; //2
                    hashMap.put("a",a);
                }
            });

            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    int b = y; //3
                    x = 1; //4
                    hashMap.put("b",b);
                }
            });

            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();

            hashSet.add("a="+hashMap.get("a")+",b="+hashMap.get("b"));
            System.out.println(hashSet);

        }

    }

}
  • 結(jié)束語

這篇博客只停留在使用層面比驻,其中還有很多原理性的東西该溯,包括Java線程內(nèi)存模型、volatile的底層實現(xiàn)原理别惦、synchronized的底層實現(xiàn)原理狈茉、指令重排等等,這些都沒講掸掸,感興趣的小伙伴可以關(guān)注我以后的文章氯庆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市扰付,隨后出現(xiàn)的幾起案子堤撵,更是在濱河造成了極大的恐慌,老刑警劉巖羽莺,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件实昨,死亡現(xiàn)場離奇詭異,居然都是意外死亡盐固,警方通過查閱死者的電腦和手機荒给,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刁卜,“玉大人志电,你說我怎么就攤上這事』着浚” “怎么了挑辆?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長孝情。 經(jīng)常有香客問我鱼蝉,道長,這世上最難降的妖魔是什么箫荡? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任蚀乔,我火速辦了婚禮,結(jié)果婚禮上菲茬,老公的妹妹穿的比我還像新娘。我一直安慰自己派撕,他們只是感情好婉弹,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著终吼,像睡著了一般镀赌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上际跪,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天商佛,我揣著相機與錄音喉钢,去河邊找鬼。 笑死良姆,一個胖子當著我的面吹牛肠虽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玛追,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼税课,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了痊剖?” 一聲冷哼從身側(cè)響起韩玩,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎陆馁,沒想到半個月后找颓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡叮贩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年击狮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妇汗。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡帘不,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出杨箭,到底是詐尸還是另有隱情寞焙,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布互婿,位于F島的核電站捣郊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏慈参。R本人自食惡果不足惜呛牲,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驮配。 院中可真熱鬧娘扩,春花似錦、人聲如沸壮锻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猜绣。三九已至灰殴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掰邢,已是汗流浹背牺陶。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工伟阔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掰伸。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓皱炉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親碱工。 傳聞我的和親對象是個殘疾皇子娃承,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

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