以下代码演示了 1000 个线程同时对 cnt 执行自增操作,操作结束之后它的值有可能小于 1000。
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class UnsafeExemple {
public class Exemple{
private int cnt=0;
public void add(){
cnt++;
}
public int res(){
return cnt;
}
}
public static void main(String[]args)throws InterruptedException{
int threadSize=1000;
UnsafeExemple e=new UnsafeExemple();
Exemple exemple=e.new Exemple();
CountDownLatch countDownLatch=new CountDownLatch(threadSize);
ExecutorService executorService= Executors.newCachedThreadPool();
for(int i=0;i<threadSize;i++){
executorService.execute(()->{
exemple.add();
// System.out.println(exemple.res());
}
);
countDownLatch.countDown();
}
countDownLatch.await();
executorService.shutdown();
System.out.println(exemple.res());
}
}
解决线程不安全的方法为对add()方法上锁
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class UnsafeExemple {
public class Exemple{
private int cnt=0;
public synchronized void add(){
cnt++;
}
public int res(){
return cnt;
}
}
public static void main(String[]args)throws InterruptedException{
int threadSize=1000;
UnsafeExemple e=new UnsafeExemple();
Exemple exemple=e.new Exemple();
CountDownLatch countDownLatch=new CountDownLatch(threadSize);
ExecutorService executorService= Executors.newCachedThreadPool();
for(int i=0;i<threadSize;i++){
executorService.execute(()->{
exemple.add();
// System.out.println(exemple.res());
}
);
countDownLatch.countDown();
}
countDownLatch.await();
executorService.shutdown();
System.out.println(exemple.res());
}
}