Java 編程下的同步代碼塊

爲了便於理解先來看看沒有加同步代碼塊的 2 組同樣功能的代碼在不同狀態下的執行結果,下面看第一組:

複製代碼
package cn.sunzn.synchronize;

public class SynchronizeCode {
   public static void main(String[] args) {
       new Thread() {
           public void run() {
               while (true) {
                   System.out.println("同步代碼");
               }
           };
       }.start();
       new Thread() {
           public void run() {
               while (true) {
                   System.out.println("SynchronizeCode");
               }
           };
       }.start();
   }
}
複製代碼

第一組代碼運行結果:

複製代碼
SynchronizeCode
SynchronizeCode
SynchronizeCode
SynchronizeCode
同步代碼
同步代碼
同步代碼
同步代碼
複製代碼

下面再來看第 2 組代碼:

複製代碼
package cn.sunzn.synchronize;

public class SynchronizeCode {
   public static void main(String[] args) {
       new Thread() {
           public void run() {
               while (true) {
                   System.out.print("同步");
                   System.out.println("代碼");
               }
           };
       }.start();
       new Thread() {
           public void run() {
               while (true) {
                   System.out.print("Synchronize");
                   System.out.println("Code");
               }
           };
       }.start();
   }
}
複製代碼

第二組代碼運行結果:

複製代碼
同步代碼
同步代碼
同步代碼
同步Code
SynchronizeCode
SynchronizeCode
SynchronizeCode
SynchronizeCode
複製代碼

顯然,第二組代碼中同一個線程下的打印輸出並沒有同時執行,這是因爲 CPU 在不同的線程間進行切換時的隨機性導致的。第二組代碼中的輸出結果“同步Code”是因爲 CPU 切換到線程 1 的時候打印輸出“同步”,但是當程序正準備打印“代碼”的時候,CUP 切換到了線程 2 打印輸出“Code”, 然後線程 2 繼續持有 CPU 資源進行打印輸出,知道 CPU 切換到線程 1。正因爲這樣的原因,當程序中包含有多個線程時,導致了同一個線程下的代碼不能同時被執行。那麼,我們如何才能保證這樣的情況不發生呢?使用同步代碼 塊。下面我們來看使用了同步代碼塊程序的運行結果:

複製代碼
package cn.sunzn.synchronize;

public class SynchronizeCode {
   public static void main(String[] args) {
       /************ 創建鎖對象 ************/
       final Object lock = new Object();
       /************ 開啓線程一 ************/
       new Thread() {
           public void run() {
               while (true) {
                   synchronized (lock) {
                       System.out.print("同步");
                       System.out.println("代碼");
                   }
               }
           };
       }.start();
       /************ 開啓線程二 ************/
       new Thread() {
           public void run() {
               while (true) {
                   synchronized (lock) {
                       System.out.print("Synchronize");
                       System.out.println("Code");
                   }
               }
           };
       }.start();
   }
}
複製代碼

運行上面的代碼我們會發現運行結果和第一組代碼的運行結果類似,這是因爲使用了相同鎖對象的同步代碼塊具有原子性,在進行執行的時候會持續的擁有 CPU 資源直到同步代碼塊執行完畢,要麼繼續持有 CPU 資源,要麼 CPU 切換到到另一個線程,這樣保證了在執行一組代碼的時候不會有其他線程插入執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章