程序清单3-1 在没有同步的情况下共享变量(不要这么做)
/** * 主线程和读线程都将访问共享变量:ready 和 number * 结果可能 * 1、 主线程先运行完,读线程后运行:读线程在控制台打印输出42, * 2、 读线程先执行完,主线程后执行:读线程在控制台打印输出0 * 3、 NoVisibility根本无法终止,读线程可能永远都看不到ready的值 * 4、 重排序(Reordering):读线程看到了主线程中顺序靠后写入的ready的值,但没看到主线程先写入的number的值 */ @NotThreadSafe public class NoVisibility { private static boolean ready; private static int number; //读线程 private static class ReaderThread extends Thread { @Override public void run() { while(!ready) Thread.yield(); System.out.println(number); } } public static void main(String[] args) { new ReaderThread().start(); number = 42; ready = true; } }
程序清单3-2 非线程安全的可变整数类
//mutable 英[ˈmju:təbl] adj. 易变的,性情不定的; @NotThreadSafe public class MutableInteger { private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } }
程序清单3-3 线程安全的可变整数类
@ThreadSafe public class SynchronizedInteger { @GuardedBy("this")private int value; public synchronized int getValue() { return value; } public synchronized void setValue(int value) { this.value = value; } }
/**asleep 状态量一旦在某个线程中被更改了,其它线程也应该看到*/ @ThreadSafe public class CountSheep { volatile boolean asleep; public void countSomeSheep() { while(!asleep) { for (int i = 0; i < 100; i++) { System.out.println("sheep"+i); } } } }