歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java多線程總結四:volatile、synchronized示例

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

日期:2017/3/1 10:55:57   编辑:Linux編程

1、synchronized保證同步

先看一個生成偶數的類

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

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

測試代碼:

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

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

Copyright © Linux教程網 All Rights Reserved