今天看了java并发编程实战,了解到java中基本类型的自增操作是非线程安全的,例如:
@NotThreadSafe public class UnsafeSequence { private int value; /** Returns a unique value. */ public int getNext() { return value++; } }
value的自增操作分为三个部分,先读后写两个操作,这两个操作不是原子的,是线程非安全的。
测试类如下:
package com.liuyao.java; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class UnSafeSequence implements Runnable{ private int value = 0; private int getNext() { return value; } public static void main(String[] args) { UnSafeSequence us = new UnSafeSequence(); ExecutorService exec = Executors.newCachedThreadPool(); for(int i=0;i<100;i++) { exec.submit(us); } exec.shutdown(); while(!exec.isTerminated()); System.out.println(us.getNext()); } @Override public void run() { for(int i=0;i<100;i++) { value++; } } }
启动100个线程,每个线程执行100次自增操作。由于读取的过程中会出现两次重复读的情况,所以最后的执行和会小于10000