1、synchronized保證同步
先看一個生成偶數的類
- package demo.thread;
-
- /**
- *這是一個int生成器的抽象類
- *
- */
- public abstract class IntGenerator {
-
- private volatile boolean canceled = false;
-
- public abstract int next();
-
- public void cancel() {
- canceled = true;
- }
-
- public boolean isCanceled() {
- return canceled;
- }
- }
- /*
- * 產生偶數
- */
- class EvenGenerator extends IntGenerator {
- private int currentEvenValue = 0;
- String s = "";
-
- @Override
- public int next() {
- <span style="color:#ff0000;">synchronized </span>(s) {
- ++currentEvenValue;
- ++currentEvenValue;
- return currentEvenValue;
- }
- }
-
- // //這樣也可以
- // public <span >synchronized </span>int next() {
- // ++currentEvenValue;
- // ++currentEvenValue;
- // return currentEvenValue;
- // }
- }
注意到在產生偶數是要加同步鎖,否則可能線程1剛好執行了一句++currentEvenValue;操作,就被線程2搶去了cpu,此時線程2執行return currentEvenValue;這時返回的就是一個奇數。加synchronized 就是兩個線程同時只能一個線程執行synchronized 塊的代碼。
測試代碼:
- package demo.thread;
-
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
-
- /*
- * 消費數字
- */
- public class EvenChecker implements Runnable {
-
- private IntGenerator generator;
- private final int id;
-
- public EvenChecker(IntGenerator g, int ident) {
- generator = g;
- id = ident;
- }
-
- public void run() {
- while (!generator.isCanceled()) {
- int val = generator.next();
- if (val % 2 != 0) {//如果不是偶數
- System.out.println(val + " not enen!");
- generator.cancel();
- }
- }
- }
-
- public static void test(IntGenerator gp, int count) {
- ExecutorService exec = Executors.newCachedThreadPool();
- for (int i = 0; i < count; i++)
- exec.execute(new EvenChecker(gp, i));
- exec.shutdown();
- }
-
- public static void test(IntGenerator gp) {
- test(gp, 10);
- }
-
- public static void main(String[] args) {
- test(new EvenGenerator());
- }
分析:如果產生偶數的類未加synchronized,那麼測試程序將會出現奇數導致退出程序。