<del id="d4fwx"><form id="d4fwx"></form></del>
      <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

            <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
          • 如何使用Synchronized關(guān)鍵字同步類方法

            本篇內(nèi)容主要講解“如何使用Synchronized關(guān)鍵字同步類方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“如何使用Synchronized關(guān)鍵字同步類方法”吧!

            10年積累的網(wǎng)站設(shè)計、網(wǎng)站制作經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先制作網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有左貢免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

            要想解決“臟數(shù)據(jù)”的問題,最簡單的方法就是使用synchronized關(guān)鍵字來使run方法同步,代碼如下:

            public synchronized void run()  {         }

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

            sychronized關(guān)鍵字只和一個對象實例綁定

            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方法是分別執(zhí)行的。要想讓method同步,必須在建立Sync類的實例時向它的構(gòu)造方法中傳入同一個Test類的實例,如下面的代碼所示:

            Sync sync1 = new Sync(test1);     不僅可以使用synchronized來同步非靜態(tài)方法,也可以使用synchronized來同步靜態(tài)方法。如可以按如下方式來定義method方法:

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

            建立Test類的對象實例如下:

            Test test = new Test();

            對于靜態(tài)方法來說,只要加上了synchronized關(guān)鍵字,這個方法就是同步的,無論是使用test.method(),還是使用Test.method()來調(diào)用method方法,method都是同步的,并不存在非靜態(tài)方法的多個實例的問題。

            在23種設(shè)計模式中的單件(Singleton)模式如果按傳統(tǒng)的方法設(shè)計,也是線程不安全的,下面的代碼是一個線程不安全的單件模式。

            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();      }  }

            在上面的代碼調(diào)用yield方法是為了使單件模式的線程不安全性表現(xiàn)出來,如果將這行去掉,上面的實現(xiàn)仍然是線程不安全的,只是出現(xiàn)的可能性小得多。

            程序的運行結(jié)果如下:

            25358555
            26399554
            7051261
            29855319
            5383406

            上面的運行結(jié)果可能在不同的運行環(huán)境上有所有同,但一般這五行輸出不會完全相同。從這個輸出結(jié)果可以看出,通過getInstance方法得到的對象實例是五個,而不是我們期望的一個。這是因為當(dāng)一個線程執(zhí)行了Thread.yield()后,就將CPU資源交給了另外一個線程。由于在線程之間切換時并未執(zhí)行到創(chuàng)建Singleton對象實例的語句,因此,這幾個線程都通過了if判斷,所以,就會產(chǎn)生了建立五個對象實例的情況(可能創(chuàng)建的是四個或三個對象實例,這取決于有多少個線程在創(chuàng)建Singleton對象之前通過了if判斷,每次運行時可能結(jié)果會不一樣)。

            要想使上面的單件模式變成線程安全的,只要為getInstance加上synchronized關(guān)鍵字即可。代碼如下:

            public static synchronized Singleton getInstance() {   }

            當(dāng)然,還有更簡單的方法,就是在定義Singleton變量時就建立Singleton對象,代碼如下:

            private static final Singleton sample = new Singleton();

            然后在getInstance方法中直接將sample返回即可。這種方式雖然簡單,但不知在getInstance方法中創(chuàng)建Singleton對象靈活。讀者可以根據(jù)具體的需求選擇使用不同的方法來實現(xiàn)單件模式。

            在使用synchronized關(guān)鍵字時有以下四點需要注意:

            1.  synchronized關(guān)鍵字不能繼承。

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

            在子類方法中加上synchronized關(guān)鍵字

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

            在子類方法中調(diào)用父類的同步方法

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

            2.  在定義接口方法時不能使用synchronized關(guān)鍵字。

            3.  構(gòu)造方法不能使用synchronized關(guān)鍵字,但可以使用下節(jié)要討論的synchronized塊來進行同步。

            4.  synchronized可以自由放置。

            在前面的例子中使用都是將synchronized關(guān)鍵字放在方法的返回類型前面。但這并不是synchronized可放置***位置。在非靜態(tài)方法中,synchronized還可以放在方法定義的最前面,在靜態(tài)方法中,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關(guān)鍵字只能用來同步方法,不能用來同步類變量,如下面的代碼也是錯誤的。

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

            雖然使用synchronized關(guān)鍵字同步方法是最安全的同步方式,但大量使用synchronized關(guān)鍵字會造成不必要的資源消耗以及性能損失。雖然從表面上看synchronized鎖定的是一個方法,但實際上synchronized鎖定的是一個類。也就是說,如果在非靜態(tài)方法method1和method2定義時都使用了synchronized,在method1未執(zhí)行完之前,method2是不能執(zhí)行的。靜態(tài)方法和非靜態(tài)方法的情況類似。但靜態(tài)和非靜態(tài)方法不會互相影響??纯慈缦碌拇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("非靜態(tài)的method1方法");      }      public synchronized void method2()      {          method("非靜態(tài)的method2方法");      }      public static synchronized void method3()      {          method("靜態(tài)的method3方法");      }      public static synchronized void method4()      {          method("靜態(tài)的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);          }      }  }

            運行結(jié)果如下:

            非靜態(tài)的method1方法
            靜態(tài)的method3方法

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

            到此,相信大家對“如何使用Synchronized關(guān)鍵字同步類方法”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

            本文題目:如何使用Synchronized關(guān)鍵字同步類方法
            本文鏈接:http://www.jbt999.com/article38/pdggsp.html

            成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)服務(wù)器托管、云服務(wù)器、營銷型網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、品牌網(wǎng)站建設(shè)

            廣告

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

            營銷型網(wǎng)站建設(shè)

              <del id="d4fwx"><form id="d4fwx"></form></del>
              <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

                    <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
                  • 超碰大香蕉97 | 日本久久网 | 国产美女全裸网站 | 蜜桃传媒在线一二三区 | 无遮挡WWW |