亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

java多線程編程之使用Synchronized關鍵字同步類方法

2019-11-26 15:43:56
字體:
來源:轉載
供稿:網友

復制代碼 代碼如下:

public synchronized void run()
{    
}

從上面的代碼可以看出,只要在void和public之間加上synchronized關鍵字,就可以使run方法同步,也就是說,對于同一個Java類的對象實例,run方法同時只能被一個線程調用,并當前的run執行完后,才能被其他的線程調用。即使當前線程執行到了run方法中的yield方法,也只是暫停了一下。由于其他線程無法執行run方法,因此,最終還是會由當前的線程來繼續執行。先看看下面的代碼:
sychronized關鍵字只和一個對象實例綁定
復制代碼 代碼如下:

class Test
  {
        public synchronized void method()
       {

       }
  }

  public class Sync implements Runnable
  {
       private Test test;
       public void run()
       {
            test.method();
       }
       public Sync(Test test)
       {
           this.test = test;
       }
       public static void main(String[] args) throws Exception
       {
           Test test1 =  new Test();
           Test test2 =  new Test();
           Sync sync1 = new Sync(test1);
           Sync sync2 = new Sync(test2);
           new Thread(sync1).start();
           new Thread(sync2).start();
       }
   }
 

在Test類中的method方法是同步的。但上面的代碼建立了兩個Test類的實例,因此,test1和test2的method方法是分別執行的。要想讓method同步,必須在建立Sync類的實例時向它的構造方法中傳入同一個Test類的實例,如下面的代碼所示:
Sync sync1 = new Sync(test1);
不僅可以使用synchronized來同步非靜態方法,也可以使用synchronized來同步靜態方法。如可以按如下方式來定義method方法:
復制代碼 代碼如下:

class Test
{
    public static synchronized void method() {   }
}

建立Test類的對象實例如下:
Test test = new Test();
對于靜態方法來說,只要加上了synchronized關鍵字,這個方法就是同步的,無論是使用test.method(),還是使用Test.method()來調用method方法,method都是同步的,并不存在非靜態方法的多個實例的問題。
在23種設計模式中的單件(Singleton)模式如果按傳統的方法設計,也是線程不安全的,下面的代碼是一個線程不安全的單件模式。

復制代碼 代碼如下:

package test;

// 線程安全的Singleton模式
class Singleton
{
    private static Singleton sample;

    private Singleton()
    {
    }
    public static Singleton getInstance()
    {
        if (sample == null)
        {
            Thread.yield(); // 為了放大Singleton模式的線程不安全性
            sample = new Singleton();
        }
        return sample;
    }
}
public class MyThread extends Thread
{
    public void run()
    {
        Singleton singleton = Singleton.getInstance();
        System.out.println(singleton.hashCode());
    }
    public static void main(String[] args)
    {
        Thread threads[] = new Thread[5];
        for (int i = 0; i < threads.length; i++)
            threads[i] = new MyThread();
        for (int i = 0; i < threads.length; i++)
            threads[i].start();
    }
}


在上面的代碼調用yield方法是為了使單件模式的線程不安全性表現出來,如果將這行去掉,上面的實現仍然是線程不安全的,只是出現的可能性小得多。
程序的運行結果如下:
復制代碼 代碼如下:

25358555
26399554
7051261
29855319
5383406

上面的運行結果可能在不同的運行環境上有所有同,但一般這五行輸出不會完全相同。從這個輸出結果可以看出,通過getInstance方法得到的對象實例是五個,而不是我們期望的一個。這是因為當一個線程執行了Thread.yield()后,就將CPU資源交給了另外一個線程。由于在線程之間切換時并未執行到創建Singleton對象實例的語句,因此,這幾個線程都通過了if判斷,所以,就會產生了建立五個對象實例的情況(可能創建的是四個或三個對象實例,這取決于有多少個線程在創建Singleton對象之前通過了if判斷,每次運行時可能結果會不一樣)。
要想使上面的單件模式變成線程安全的,只要為getInstance加上synchronized關鍵字即可。代碼如下:
public static synchronized Singleton getInstance() {   }
當然,還有更簡單的方法,就是在定義Singleton變量時就建立Singleton對象,代碼如下:
private static final Singleton sample = new Singleton();
然后在getInstance方法中直接將sample返回即可。這種方式雖然簡單,但不知在getInstance方法中創建Singleton對象靈活。讀者可以根據具體的需求選擇使用不同的方法來實現單件模式。

在使用synchronized關鍵字時有以下四點需要注意:

1.  synchronized關鍵字不能繼承。
雖然可以使用synchronized來定義方法,但synchronized并不屬于方法定義的一部分,因此,synchronized關鍵字不能被繼承。如果在父類中的某個方法使用了synchronized關鍵字,而在子類中覆蓋了這個方法,在子類中的這個方法默認情況下并不是同步的,而必須顯式地在子類的這個方法中加上synchronized關鍵字才可以。當然,還可以在子類方法中調用父類中相應的方法,這樣雖然子類中的方法不是同步的,但子類調用了父類的同步方法,因此,子類的方法也就相當于同步了。這兩種方式的例子代碼如下:
在子類方法中加上synchronized關鍵字

復制代碼 代碼如下:

class Parent
{
    public synchronized void method() {   }
}
class Child extends Parent
{
    public synchronized void method() {   }
}

在子類方法中調用父類的同步方法

復制代碼 代碼如下:

class Parent
{
    public synchronized void method() {   }
}
class Child extends Parent
{
    public void method() { super.method();   }
}

2.  在定義接口方法時不能使用synchronized關鍵字。
3.  構造方法不能使用synchronized關鍵字,但可以使用下節要討論的synchronized塊來進行同步。
4.  synchronized可以自由放置。
在前面的例子中使用都是將synchronized關鍵字放在方法的返回類型前面。但這并不是synchronized可放置唯一位置。在非靜態方法中,synchronized還可以放在方法定義的最前面,在靜態方法中,synchronized可以放在static的前面,代碼如下:

復制代碼 代碼如下:

public synchronized void method();
synchronized public void method();
public static synchronized void method();
public synchronized static void method();
synchronized public static void method();

但要注意,synchronized不能放在方法返回類型的后面,如下面的代碼是錯誤的:

復制代碼 代碼如下:

public void synchronized method();
public static void synchronized method();

synchronized關鍵字只能用來同步方法,不能用來同步類變量,如下面的代碼也是錯誤的。

復制代碼 代碼如下:

public synchronized int n = 0;
public static synchronized int n = 0;

雖然使用synchronized關鍵字同步方法是最安全的同步方式,但大量使用synchronized關鍵字會造成不必要的資源消耗以及性能損失。雖然從表面上看synchronized鎖定的是一個方法,但實際上synchronized鎖定的是一個類。也就是說,如果在非靜態方法method1和method2定義時都使用了synchronized,在method1未執行完之前,method2是不能執行的。靜態方法和非靜態方法的情況類似。但靜態和非靜態方法不會互相影響??纯慈缦碌拇a:

復制代碼 代碼如下:

package test;

public class MyThread1 extends Thread
{
    public String methodName;

    public static void method(String s)
    {
        System.out.println(s);
        while (true)

    }
    public synchronized void method1()
    {
        method("非靜態的method1方法");
    }
    public synchronized void method2()
    {
        method("非靜態的method2方法");
    }
    public static synchronized void method3()
    {
        method("靜態的method3方法");
    }
    public static synchronized void method4()
    {
        method("靜態的method4方法");
    }
    public void run()
    {
        try
        {
            getClass().getMethod(methodName).invoke(this);
        }
        catch (Exception e)
        {
        }
    }
    public static void main(String[] args) throws Exception
    {
        MyThread1 myThread1 = new MyThread1();
        for (int i = 1; i <= 4; i++)
        {
            myThread1.methodName = "method" + String.valueOf(i);
            new Thread(myThread1).start();
            sleep(100);
        }
    }
}

運行結果如下:

復制代碼 代碼如下:

非靜態的method1方法
靜態的method3方法

從上面的運行結果可以看出,method2和method4在method1和method3未結束之前不能運行。因此,我們可以得出一個結論,如果在類中使用synchronized關鍵字來定義非靜態方法,那將影響這個中的所有使用synchronized關鍵字定義的非靜態方法。如果定義的是靜態方法,那么將影響類中所有使用synchronized關鍵字定義的靜態方法。這有點象數據表中的表鎖,當修改一條記錄時,系統就將整個表都鎖住了,因此,大量使用這種同步方式會使程序的性能大幅度下降。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久综合电影一区| 亚洲日韩欧美视频一区| 久久久亚洲精选| 久久伊人精品天天| 欧美成人在线影院| 日韩中文字幕免费看| 日本韩国欧美精品大片卡二| 色综合久综合久久综合久鬼88| 欧美高清视频在线播放| 国产精品久久久久久久久男| 日韩av电影中文字幕| 午夜精品理论片| 国产精品久久久久久久久久三级| 亚洲a区在线视频| 日韩在线免费观看视频| 欧美激情一区二区三区在线视频观看| 国产精品三级久久久久久电影| 在线观看欧美日韩国产| 性欧美长视频免费观看不卡| 6080yy精品一区二区三区| 欧美一级免费视频| 国产亚洲欧美aaaa| 姬川优奈aav一区二区| 欧美亚洲激情在线| 国产精品中文字幕久久久| 国模精品一区二区三区色天香| 97超碰色婷婷| 97精品视频在线播放| 国产精品久久久久久久久久东京| 精品一区二区三区四区在线| 精品国产一区二区三区久久狼5月| 亚洲欧美一区二区三区四区| 国产精品一二三视频| 色综合91久久精品中文字幕| 午夜精品一区二区三区在线视| 精品国产一区二区三区久久狼5月| 亚洲国产小视频| 日韩亚洲欧美成人| 久久黄色av网站| 亚洲精品一区二区三区不| 久久av红桃一区二区小说| 国产成人精品一区二区在线| 亚洲成在人线av| 国产亚洲精品va在线观看| www.亚洲免费视频| 亚洲精品欧美日韩专区| 久久福利视频导航| 91久久久亚洲精品| 俺去亚洲欧洲欧美日韩| 欧美日本在线视频中文字字幕| 国产一区二区三区日韩欧美| 亚洲成人精品视频在线观看| 久99九色视频在线观看| 国产成人激情视频| 亚洲综合视频1区| 国产精品久久久久久五月尺| 国产91|九色| 成人免费高清完整版在线观看| 亚洲色图色老头| 国产日韩精品一区二区| 亚洲视频日韩精品| 97视频在线观看视频免费视频| 欧美亚洲国产精品| 久久久久久久久国产精品| 国产精品美女www爽爽爽视频| 国产精品黄色av| 久久久久久久久国产精品| 亚洲第一色中文字幕| 国产香蕉一区二区三区在线视频| 亚洲女人天堂色在线7777| 欧美亚洲国产日本| 国产色婷婷国产综合在线理论片a| 亚洲三级黄色在线观看| 国产一级揄自揄精品视频| 亚洲第一精品夜夜躁人人爽| 欧美国产日韩免费| 国产精品av在线播放| 欧美成人国产va精品日本一级| 日韩中文字幕第一页| 国产精品欧美一区二区三区奶水| 国产精品夜色7777狼人| 日韩av不卡电影| 91香蕉嫩草神马影院在线观看| 日韩av中文字幕在线播放| 久久精品免费电影| 亚洲人永久免费| 在线观看欧美成人| 亚洲香蕉成视频在线观看| 欧洲精品毛片网站| 久久6精品影院| 国产成人精品视频在线观看| 国产精品人成电影在线观看| 国产综合久久久久久| 欧美久久精品一级黑人c片| 在线播放日韩精品| 日韩中文字幕国产精品| 一区二区三区视频在线| 亚洲人成网站在线播| 久久成人综合视频| 久久亚洲国产成人| 96精品视频在线| 欧美极品美女电影一区| 亚洲综合第一页| 日韩一区二区福利| 热re99久久精品国产66热| 夜夜嗨av色一区二区不卡| 精品国产一区二区三区四区在线观看| 精品久久久久久久久久国产| 2019中文在线观看| 日本欧美黄网站| 久久国产精品久久久| 亚洲第一页在线| 日韩美女主播视频| 欧美在线中文字幕| 国产自产女人91一区在线观看| 国产日韩一区在线| 97精品一区二区视频在线观看| 国产亚洲欧美另类中文| 成人中文字幕在线观看| 亚洲自拍欧美色图| 日韩在线观看成人| 欧美一区三区三区高中清蜜桃| 97香蕉久久超级碰碰高清版| 亚洲第一福利网站| 日韩欧美极品在线观看| 久久久久久久久91| 午夜精品蜜臀一区二区三区免费| 在线日韩欧美视频| 亚洲激情 国产| 美女精品久久久| 国产女人18毛片水18精品| 国产精品主播视频| 国产福利精品在线| 亚洲国产欧美精品| 国产欧美一区二区三区久久人妖| 九九九热精品免费视频观看网站| 精品国产自在精品国产浪潮| 日韩精品中文字幕在线观看| 亚洲欧美日韩成人| 九九热最新视频//这里只有精品| 亚洲精品自产拍| 北条麻妃一区二区三区中文字幕| 久久久999精品免费| 日韩精品中文在线观看| 亚洲国产精品va在看黑人| 久久人人爽人人爽人人片av高请| 日本a级片电影一区二区| 国产一区二区丝袜高跟鞋图片| 日本a级片电影一区二区| 亚洲国产黄色片| 在线成人激情黄色| 久久av.com| 亚洲欧美日韩精品久久亚洲区| 国产精品扒开腿做爽爽爽的视频| 久久久久国产精品一区| 亚洲第一视频网站| 深夜福利日韩在线看| 日韩精品免费综合视频在线播放| 国产视频综合在线| 欧美日韩激情视频| 国产精品第1页| 欧美成人黄色小视频| 久久久女人电视剧免费播放下载| 亚洲摸下面视频|