中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

synchronized傳統(tǒng)線程互斥技術(shù)怎么用

本文小編為大家詳細(xì)介紹“synchronized傳統(tǒng)線程互斥技術(shù)怎么用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“synchronized傳統(tǒng)線程互斥技術(shù)怎么用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。

我們提供的服務(wù)有:成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、薩嘎ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的薩嘎網(wǎng)站制作公司

在多個(gè)線程同時(shí)操作相同資源的時(shí)候,就會(huì)遇到并發(fā)的問題,如銀行轉(zhuǎn)賬啊、售票系統(tǒng)啊等。為了避免這些問題的出現(xiàn),我們可以使用 synchronized 關(guān)鍵字來解決,下面針對(duì) synchronized 常見的用法做一個(gè)總結(jié)。首先寫一個(gè)存在并發(fā)問題的程序,如下:

public class TraditionalThreadSynchronized {
    public static void main(String[] args) {
        //在靜態(tài)方法中不能new內(nèi)部類的實(shí)例對(duì)象
        //private Outputer outputer = new Outputer();
        new TraditionalThreadSynchronized().init();
    }
    private void init() {
        final Outputer outputer = new Outputer();
        //線程1打?。篸uoxiancheng
        new Thread(new Runnable() {         
            @Override
            public void run() {
                while(true) {
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    outputer.output1("duoxiancheng");
                }
            }
        }).start();;
        //線程2打?。篹son15
        new Thread(new Runnable() {         
            @Override
            public void run() {
                while(true) {
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    outputer.output1("eson15");
                }
            }
        }).start();;
    }
    static class Outputer {
        //自定義一個(gè)字符串打印方法,一個(gè)個(gè)字符的打印
        public void output1(String name) {
            int len = name.length();
            for(int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println("");     
        }       
    }
}

在內(nèi)部類 Outputer 中定義了一個(gè)打印字符串的方法,一個(gè)字符一個(gè)字符的打印,這樣比較容易直觀的看出并發(fā)問題,因?yàn)樽址樞虼騺y了就說明出現(xiàn)問題了。然后在 init 方法中開啟兩個(gè)線程,一個(gè)線程打印 “duoxiancheng” ,另一個(gè)線程打印 “eson15”??匆幌逻\(yùn)行結(jié)果:

eson15duoxianche
ng
eson15
duoxiancheng
duoxiancheng
eson15
esduoxiancheng
on15
duoxiancheng

從輸出的結(jié)果中可以看到,已經(jīng)出現(xiàn)問題了,為了解決這個(gè)問題,可以使用 synchronized 同步代碼塊來對(duì)公共部分進(jìn)行同步操作,但是需要給它一把鎖,這把鎖是一個(gè)對(duì)象,可以是任意一個(gè)對(duì)象,但是前提是,兩個(gè)線程使用的必須是同一個(gè)對(duì)象鎖才可以,這很好理解。那么下面在 output1() 方法中加入 synchronized 代碼塊:

static class Outputer {
    private String token = ""; //定義一個(gè)鎖
    public void output1(String name) {
        synchronized(token) //任何一個(gè)對(duì)象都可以作為參數(shù),但是該對(duì)象對(duì)于兩個(gè)線程來說是同一個(gè)才行
        //如果用name就不行了,因?yàn)椴煌木€程進(jìn)來name是不一樣的,不是同一個(gè)name
        {
            int len = name.length();
            for(int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println("");     
        }
    }
}

經(jīng)過上面的改造,線程安全問題就基本解決了,但是還可以再往下引申,如果在方法上加 synchronized 關(guān)鍵字的話,那么這個(gè)同步鎖是什么呢?我們?cè)?Outputer 類中再寫一個(gè) output2() 方法:

static class Outputer {
    private String token = ""; //定義一個(gè)鎖
    public void output1(String name) {
        synchronized(token) //任何一個(gè)對(duì)象都可以作為參數(shù),但是該對(duì)象對(duì)于兩個(gè)線程來說是同一個(gè)才行
        {
            int len = name.length();
            for(int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println("");     
        }
    }   
    public synchronized void output2(String name) {
        int len = name.length();
        for(int i = 0; i < len; i++) {
            System.out.print(name.charAt(i));
        }
        System.out.println("");     
    }   
}

方法內(nèi)部實(shí)現(xiàn)邏輯一模一樣,唯一不同的就是 synchronized 加在了方法上,那么我們讓 init() 方法中的兩個(gè)線程中,一個(gè)調(diào)用 output1(Stringname) 方法,另一個(gè)調(diào)用 output2(Stringname) 方法,從結(jié)果中能看出,線程安全問題又出現(xiàn)了。產(chǎn)生問題的原因不難發(fā)現(xiàn):現(xiàn)在兩個(gè)方法都加了 synchronized,但是兩個(gè)線程在調(diào)用兩個(gè)不同的方法還是出現(xiàn)了問題,也就是說,還是各玩各的……那么問題就出在這個(gè)鎖上,說明兩者并沒有使用同一把鎖!
如果我們把 output1() 方法中 synchronized 中的 token 改成 this,再運(yùn)行就沒問題了,這說明一點(diǎn):synchronized 關(guān)鍵字修飾方法的時(shí)候,同步鎖是 this,即等效于代碼塊 synchronized(this){...}。
再繼續(xù)往下引申,現(xiàn)在在 Outputer 類中再寫一個(gè)靜態(tài)方法 output3(Stringname),并且也讓 synchronized 去修飾這個(gè)靜態(tài)方法。

static class Outputer {
    private String token = ""; //定義一個(gè)鎖
    public void output1(String name) {
        synchronized(token) //任何一個(gè)對(duì)象都可以作為參數(shù),但是該對(duì)象對(duì)于兩個(gè)線程來說是同一個(gè)才行
        {
            int len = name.length();
            for(int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println("");     
        }
    }   
    public static synchronized void output3(String name) {
        int len = name.length();
        for(int i = 0; i < len; i++) {
            System.out.print(name.charAt(i));
        }
        System.out.println("");     
        }   
    }
}

然后在 init() 方法中一個(gè)線程調(diào)用 output1() 方法,另一個(gè)線程調(diào)用 output3() 方法。毫無疑問,肯定又會(huì)出現(xiàn)線程安全問題。但是如何解決呢?因?yàn)?static 方法在類加載的時(shí)候就加載了,所以這個(gè)鎖應(yīng)該是類的字節(jié)碼對(duì)象。那么將 token 改為 Outputer.class 就解決問題了,這說明一點(diǎn):synchronized 關(guān)鍵字修飾 static 方法的時(shí)候,同步鎖是該類的字節(jié)碼對(duì)象,即等效于代碼塊 synchronized(classname.class){...}。
最后再總結(jié)一下:

  • 同步代碼塊的鎖是任意對(duì)象。只要不同的線程都執(zhí)行同一個(gè)同步代碼塊的時(shí)候,這個(gè)鎖隨便設(shè)。

  • 同步函數(shù)的鎖是固定的 this。當(dāng)需要和同步函數(shù)中的邏輯實(shí)行同步的時(shí)候,代碼塊中的鎖必須為 this。

  • 靜態(tài)同步函數(shù)的鎖是該函數(shù)所屬類的字節(jié)碼文件對(duì)象。該對(duì)象可以用 this.getClass() 方法獲取,也可以使用 當(dāng)前類名.class 表示。

讀到這里,這篇“synchronized傳統(tǒng)線程互斥技術(shù)怎么用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)頁名稱:synchronized傳統(tǒng)線程互斥技術(shù)怎么用
鏈接分享:http://www.rwnh.cn/article48/pcoeep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、營銷型網(wǎng)站建設(shè)、自適應(yīng)網(wǎng)站全網(wǎng)營銷推廣、建站公司、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名
新蔡县| 连南| 西乡县| 清水县| 麻城市| 雅安市| 沙雅县| 无棣县| 湘潭县| 隆德县| 日照市| 石门县| 沁水县| 始兴县| 历史| 铁岭县| 佛冈县| 鹤峰县| 登封市| 平阴县| 外汇| 衡阳市| 西藏| 道孚县| 贺州市| 平遥县| 罗江县| 安陆市| 洛隆县| 鹰潭市| 兴业县| 岳阳县| 黔江区| 古田县| 新平| 安福县| 浪卡子县| 方山县| 颍上县| 仲巴县| 漳州市|