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 style="color:#ff0000;">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,那么测试程序将会出现奇数导致退出程序。

  • 1
  • 2
  • 下一页

相关内容