<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    tbwshc

    Java線程:線程的同步-同步方法

     線程的同步是保證多線程安全訪問(wèn)競(jìng)爭(zhēng)資源的一種手段。
        線程的同步是Java多線程編程的難點(diǎn),往往開(kāi)發(fā)者搞不清楚什么是競(jìng)爭(zhēng)資源、什么時(shí)候需要考慮同步,怎么同步等等問(wèn)題,當(dāng)然,這些問(wèn)題沒(méi)有很明確的答案,但有些原則問(wèn)題需要考慮,是否有競(jìng)爭(zhēng)資源被同時(shí)改動(dòng)的問(wèn)題?
     
        在本文之前,請(qǐng)參閱《Java線程:線程的同步與鎖》,本文是在此基礎(chǔ)上所寫(xiě)的。
     
        對(duì)于同步,在具體的Java代碼中需要完成一下兩個(gè)操作:
        把競(jìng)爭(zhēng)訪問(wèn)的資源標(biāo)識(shí)為private;
        同步哪些修改變量的代碼,使用synchronized關(guān)鍵字同步方法或代碼。
        當(dāng)然這不是唯一控制并發(fā)安全的途徑。
     
        synchronized關(guān)鍵字使用說(shuō)明
        synchronized只能標(biāo)記非抽象的方法,不能標(biāo)識(shí)成員變量。
     
        為了演示同步方法的使用,構(gòu)建了一個(gè)信用卡賬戶(hù),起初信用額為100w,然后模擬透支、存款等多個(gè)操作。顯然銀行賬戶(hù)User對(duì)象是個(gè)競(jìng)爭(zhēng)資源,而多個(gè)并發(fā)操作的是賬戶(hù)方法oper(int x),當(dāng)然應(yīng)該在此方法上加上同步,并將賬戶(hù)的余額設(shè)為私有變量,禁止直接訪問(wèn)。
     
     
    /**
    * Java線程:線程的同步
    *
    * @author leizhimin 2009-11-4 11:23:32
    */

    public class Test {
            public static void main(String[] args) {
                    User u = new User("張三", 100);
                    MyThread t1 = new MyThread("線程A", u, 20);
                    MyThread t2 = new MyThread("線程B", u, -60);
                    MyThread t3 = new MyThread("線程C", u, -80);
                    MyThread t4 = new MyThread("線程D", u, -30);
                    MyThread t5 = new MyThread("線程E", u, 32);
                    MyThread t6 = new MyThread("線程F", u, 21);

                    t1.start();
                    t2.start();
                    t3.start();
                    t4.start();
                    t5.start();
                    t6.start();
            }
    }

    class MyThread extends Thread {
            private User u;
            private int y = 0;

            MyThread(String name, User u, int y) {
                    super(name);
                    this.u = u;
                    this.y = y;
            }

            public void run() {
                    u.oper(y);
            }
    }

    class User {
            private String code;
            private int cash;

            User(String code, int cash) {
                    this.code = code;
                    this.cash = cash;
            }

            public String getCode() {
                    return code;
            }

            public void setCode(String code) {
                    this.code = code;
            }

            /**
             * 業(yè)務(wù)方法
             * @param x 添加x萬(wàn)元
             */

            public synchronized void oper(int x) {
                    try {
                            Thread.sleep(10L);
                            this.cash += x;
                            System.out.println(Thread.currentThread().getName() + "運(yùn)行結(jié)束,增加“" + x + "”,當(dāng)前用戶(hù)賬戶(hù)余額為:" + cash);
                            Thread.sleep(10L);
                    } catch (InterruptedException e) {
                            e.printStackTrace();
                    }
            }

            @Override
            public String toString() {
                    return "User{" +
                                    "code='" + code + '\'' +
                                    ", cash=" + cash +
                                    '}';
            }
    }
     
        輸出結(jié)果:
    線程A運(yùn)行結(jié)束,增加“20”,當(dāng)前用戶(hù)賬戶(hù)余額為:120
    線程F運(yùn)行結(jié)束,增加“21”,當(dāng)前用戶(hù)賬戶(hù)余額為:141
    線程E運(yùn)行結(jié)束,增加“32”,當(dāng)前用戶(hù)賬戶(hù)余額為:173
    線程C運(yùn)行結(jié)束,增加“-80”,當(dāng)前用戶(hù)賬戶(hù)余額為:93
    線程B運(yùn)行結(jié)束,增加“-60”,當(dāng)前用戶(hù)賬戶(hù)余額為:33
    線程D運(yùn)行結(jié)束,增加“-30”,當(dāng)前用戶(hù)賬戶(hù)余額為:3

    Process finished with exit code 0
     
     
        反面教材,不同步的情況,也就是去掉oper(int x)方法的synchronized修飾符,然后運(yùn)行程序,結(jié)果如下:
    線程A運(yùn)行結(jié)束,增加“20”,當(dāng)前用戶(hù)賬戶(hù)余額為:61
    線程D運(yùn)行結(jié)束,增加“-30”,當(dāng)前用戶(hù)賬戶(hù)余額為:63
    線程B運(yùn)行結(jié)束,增加“-60”,當(dāng)前用戶(hù)賬戶(hù)余額為:3
    線程F運(yùn)行結(jié)束,增加“21”,當(dāng)前用戶(hù)賬戶(hù)余額為:61
    線程E運(yùn)行結(jié)束,增加“32”,當(dāng)前用戶(hù)賬戶(hù)余額為:93
    線程C運(yùn)行結(jié)束,增加“-80”,當(dāng)前用戶(hù)賬戶(hù)余額為:61

    Process finished with exit code 0
     
        很顯然,上面的結(jié)果是錯(cuò)誤的,導(dǎo)致錯(cuò)誤的原因是多個(gè)線程并發(fā)訪問(wèn)了競(jìng)爭(zhēng)資源u,tb并對(duì)u的屬性做了改動(dòng)。
     
        可見(jiàn)同步的重要性。
     
     
        注意:
        通過(guò)前文可知,線程退出同步方法時(shí)將釋放掉方法所屬對(duì)象的鎖,但還應(yīng)該注意的是,同步方法中還可以使用特定的方法對(duì)線程進(jìn)行調(diào)度。這些方法來(lái)自于java.lang.Object類(lèi)。
     
    void notify()    
                        喚醒在此對(duì)象監(jiān)視器上等待的單個(gè)線程。    
    void notifyAll()    
                        喚醒在此對(duì)象監(jiān)視器上等待的所有線程。    
    void wait()    
                        導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的 notify() 方法或 notifyAll() 方法。    
    void wait(long timeout)    
                        導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的 notify() 方法或 notifyAll() 方法,或者超過(guò)指定的時(shí)間量。    
    void wait(long timeout, int nanos)    
                        導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對(duì)象的 notify() 方法或 notifyAll() 方法,或者其他某個(gè)線程中斷當(dāng)前線程,或者已超過(guò)某個(gè)實(shí)際時(shí)間量。
     
        結(jié)合以上方法,處理多線程同步與互斥問(wèn)題非常重要,著名的生產(chǎn)者-消費(fèi)者例子就是一個(gè)經(jīng)典的例子,任何語(yǔ)言多線程必學(xué)的例子。

    posted on 2012-08-09 11:40 chen11-1 閱讀(1203) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 99久久99这里只有免费的精品 | 日本在线观看免费高清| 免费v片视频在线观看视频| CAOPORN国产精品免费视频| 亚洲欧洲精品国产区| 国产大片51精品免费观看| 最近中文字幕大全免费版在线| 亚洲av无码久久忘忧草| 亚洲A丁香五香天堂网| 无码专区AAAAAA免费视频| 亚洲色www永久网站| 国产gv天堂亚洲国产gv刚刚碰| 4444www免费看| 日本中文字幕免费看| 久久久久亚洲精品无码蜜桃| 国产美女做a免费视频软件| 好紧我太爽了视频免费国产| 亚洲国产精品网站在线播放 | 亚洲日韩精品无码专区| 亚洲色婷婷六月亚洲婷婷6月| 国产男女爽爽爽爽爽免费视频| 免费播放美女一级毛片| 亚洲精品视频在线观看视频| 2048亚洲精品国产| 成人毛片18女人毛片免费视频未 | 97无码免费人妻超级碰碰夜夜| 一个人免费观看视频在线中文 | av电影在线免费看| 亚洲午夜理论片在线观看| 亚洲AV区无码字幕中文色| 亚洲国产一区明星换脸| 久久精品无码一区二区三区免费 | 一区二区三区四区免费视频 | 99久久久国产精品免费无卡顿| 午夜不卡AV免费| 亚洲AV永久无码精品放毛片| 亚洲成a人片在线观看中文app| 亚洲精品无码久久久久sm| 免费jjzz在线播放国产| 成人免费福利电影| 免费视频爱爱太爽了|