在java中多线程访问同一数据时,会出现数据不一致的问题。java中的自增操作需要多步完成,而且不是原子性操作控制。下面的代码说明了问题,源自java编程思想
</pre><pre code_snippet_id="1623662" snippet_file_name="blog_20160325_2_1202041" name="code" class="java">package synchonize;
public class EvenGenerator extends IntGenerator {
private int currentEvenValue = 0;
public int next(){
++currentEvenValue;
Thread.yield();
++currentEvenValue;
return currentEvenValue;
}
public static void main(String []args){
EvenChecker.test(new EvenGenerator());
}
}
package synchonize;
public abstract class IntGenerator {
private volatile boolean canceled = false;
public abstract int next();
public void cancel(){
canceled = true;
}
public boolean isCanceled(){
return canceled;
}
}
package synchonize;
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 id){
this.generator = g;
this.id = id;
}
public void run() {
// TODO Auto-generated method stub
while(!generator.isCanceled()){
int val = generator.next();
if(val %2 !=0){
System.out.println(val + "not even!");
generator.cancel();
}
}
}
public static void test(IntGenerator gp, int count){
System.out.println("press control-c to exit");
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);
}
}
好不容易调出这个结果来
press control-c to exit
5not even!
3not even!
7not even!
3not even!