歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java多線程總結四:volatile、synchronized示例

1、synchronized保證同步

先看一個生成偶數的類

  1. package demo.thread;  
  2.   
  3. /** 
  4.  *這是一個int生成器的抽象類 
  5.  *  
  6.  */  
  7. public abstract class IntGenerator {  
  8.       
  9.     private volatile boolean canceled = false;  
  10.   
  11.     public abstract int next();  
  12.   
  13.     public void cancel() {  
  14.         canceled = true;  
  15.     }  
  16.   
  17.     public boolean isCanceled() {  
  18.         return canceled;  
  19.     }  
  20. }   
 
  1. /* 
  2.  * 產生偶數 
  3.  */  
  4. class EvenGenerator extends IntGenerator {  
  5.     private int currentEvenValue = 0;  
  6.     String s = "";  
  7.   
  8.     @Override  
  9.     public int next() {  
  10.         <span style="color:#ff0000;">synchronized </span>(s) {  
  11.             ++currentEvenValue;  
  12.             ++currentEvenValue;  
  13.             return currentEvenValue;  
  14.         }  
  15.     }  
  16.   
  17. //  //這樣也可以   
  18. //  public <span >synchronized </span>int next() {   
  19. //          ++currentEvenValue;   
  20. //          ++currentEvenValue;   
  21. //          return currentEvenValue;   
  22. //  }   
  23. }

注意到在產生偶數是要加同步鎖,否則可能線程1剛好執行了一句++currentEvenValue;操作,就被線程2搶去了cpu,此時線程2執行return currentEvenValue;這時返回的就是一個奇數。加synchronized 就是兩個線程同時只能一個線程執行synchronized 塊的代碼。

測試代碼:

  1. package demo.thread;  
  2.   
  3. import java.util.concurrent.ExecutorService;  
  4. import java.util.concurrent.Executors;  
  5.   
  6. /* 
  7.  * 消費數字 
  8.  */  
  9. public class EvenChecker implements Runnable {  
  10.       
  11.     private IntGenerator generator;  
  12.     private final int id;  
  13.   
  14.     public EvenChecker(IntGenerator g, int ident) {  
  15.         generator = g;  
  16.         id = ident;  
  17.     }  
  18.   
  19.     public void run() {  
  20.         while (!generator.isCanceled()) {  
  21.             int val = generator.next();  
  22.             if (val % 2 != 0) {//如果不是偶數   
  23.                 System.out.println(val + " not enen!");  
  24.                 generator.cancel();  
  25.             }  
  26.         }  
  27.     }  
  28.   
  29.     public static void test(IntGenerator gp, int count) {  
  30.         ExecutorService exec = Executors.newCachedThreadPool();  
  31.         for (int i = 0; i < count; i++)  
  32.             exec.execute(new EvenChecker(gp, i));  
  33.         exec.shutdown();  
  34.     }  
  35.   
  36.     public static void test(IntGenerator gp) {  
  37.         test(gp, 10);  
  38.     }  
  39.   
  40.     public static void main(String[] args) {  
  41.         test(new EvenGenerator());  
  42.     }    

分析:如果產生偶數的類未加synchronized,那麼測試程序將會出現奇數導致退出程序。

Copyright © Linux教程網 All Rights Reserved