如何证明 i++ 不是原子的
How to prove i++ is not atomic
众所周知,i++在java中不是原子的,所以我试着写一个程序来证明。
我的想法是新建几个线程并在每个线程内增加计数(这是 Main class 中的静态字段)。
如果
threadNum * iteration > count,
然后我们可以证明 i++ 不是原子的,但实际上我总是让它们相等。
这是我的代码:
import java.util.ArrayList;
import java.util.List;
public class ConcurrentTest{
private static int count = 0;
public static void main(String[] args) throws Exception{
List<Thread> threads = new ArrayList<>();
for(int i = 0; i<12; ++i){
threads.add(new Thread(() -> {
for(int j=0; j<1000000; ++j) {
count++;
}
}));
}
for(Thread t: threads){
t.start();
t.join();
}
System.out.println(count);
}
}
结果是 12000000。
无论我如何改变上面程序中的 i 和 j,i*j === count.
我不知道这是否有帮助:这个程序已经在 JRE 6、7 和 8 上测试过。我还没有在 Java 5 或更早的版本上测试过它。
join
方法使当前正在执行的线程等待调用它的线程完成。在您的代码中,您启动一个线程,然后等待它完成,然后启动另一个线程。
改变
for(Thread t: threads){
t.start();
t.join();
}
至
for(Thread t: threads){
t.start();
}
for(Thread t: threads){
t.join();
}
这将启动您的所有线程 运行,然后等待它们全部完成。
改变
for(Thread t: threads){
t.start();
t.join();
}
在
for(Thread t: threads){
t.start();
}
for(Thread t: threads){
t.join();
}
这样它会 运行 多线程,而在你的方式中一次执行一个线程。
众所周知,i++在java中不是原子的,所以我试着写一个程序来证明。
我的想法是新建几个线程并在每个线程内增加计数(这是 Main class 中的静态字段)。
如果
threadNum * iteration > count,
然后我们可以证明 i++ 不是原子的,但实际上我总是让它们相等。
这是我的代码:
import java.util.ArrayList;
import java.util.List;
public class ConcurrentTest{
private static int count = 0;
public static void main(String[] args) throws Exception{
List<Thread> threads = new ArrayList<>();
for(int i = 0; i<12; ++i){
threads.add(new Thread(() -> {
for(int j=0; j<1000000; ++j) {
count++;
}
}));
}
for(Thread t: threads){
t.start();
t.join();
}
System.out.println(count);
}
}
结果是 12000000。
无论我如何改变上面程序中的 i 和 j,i*j === count.
我不知道这是否有帮助:这个程序已经在 JRE 6、7 和 8 上测试过。我还没有在 Java 5 或更早的版本上测试过它。
join
方法使当前正在执行的线程等待调用它的线程完成。在您的代码中,您启动一个线程,然后等待它完成,然后启动另一个线程。
改变
for(Thread t: threads){
t.start();
t.join();
}
至
for(Thread t: threads){
t.start();
}
for(Thread t: threads){
t.join();
}
这将启动您的所有线程 运行,然后等待它们全部完成。
改变
for(Thread t: threads){
t.start();
t.join();
}
在
for(Thread t: threads){
t.start();
}
for(Thread t: threads){
t.join();
}
这样它会 运行 多线程,而在你的方式中一次执行一个线程。