多线程和 AtomicInteger
Multiple threads and AtomicInteger
我从原子学教程中获取了这段代码,它说:-
"By using AtomicInteger as a replacement for Integer we're able to increment the number concurrently in a thread-safe manor without synchronizing the access to the variable. The method incrementAndGet() is an atomic operation so we can safely call this method from multiple threads."
它说这会 return 正确的结果,1000 但是两个实例都没有达到 1000,它们通常要少得多,例如
test1 result = 532
test2 result = 128
怎么了?
public class AtomicsTest {
public static void main(String... args){
AtomicsTest test = new AtomicsTest();
test.test1();
test.test2();
}
public void test1() {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newSingleThreadExecutor();
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
System.out.println("test1 result = "+ atomicInt.get());
executor.shutdown();
}
public void test2() {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newFixedThreadPool(2);
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
System.out.println("test2 result = " + atomicInt.get());
executor.shutdown();
}
}
您的问题是您在提交线程后立即打印值,尽管并非所有线程都必须完成。
public void test1() {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newSingleThreadExecutor();
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
// All threads submitted (not necessarily finished)
System.out.println("test1 result = "+ atomicInt.get());
executor.shutdown();
// Threads are still not necessarily done
}
如果您在打印值之前明确等待执行程序服务完成,您应该会看到预期的结果:
public void test1() {
try {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newSingleThreadExecutor();
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
executor.shutdown();
// Wait a maximum of ~a million billion years
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
System.out.println("test1 result = "+ atomicInt.get());
}
catch (InterruptedException ex)
{
// Oh no!
}
}
我从原子学教程中获取了这段代码,它说:-
"By using AtomicInteger as a replacement for Integer we're able to increment the number concurrently in a thread-safe manor without synchronizing the access to the variable. The method incrementAndGet() is an atomic operation so we can safely call this method from multiple threads."
它说这会 return 正确的结果,1000 但是两个实例都没有达到 1000,它们通常要少得多,例如
test1 result = 532
test2 result = 128
怎么了?
public class AtomicsTest {
public static void main(String... args){
AtomicsTest test = new AtomicsTest();
test.test1();
test.test2();
}
public void test1() {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newSingleThreadExecutor();
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
System.out.println("test1 result = "+ atomicInt.get());
executor.shutdown();
}
public void test2() {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newFixedThreadPool(2);
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
System.out.println("test2 result = " + atomicInt.get());
executor.shutdown();
}
}
您的问题是您在提交线程后立即打印值,尽管并非所有线程都必须完成。
public void test1() {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newSingleThreadExecutor();
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
// All threads submitted (not necessarily finished)
System.out.println("test1 result = "+ atomicInt.get());
executor.shutdown();
// Threads are still not necessarily done
}
如果您在打印值之前明确等待执行程序服务完成,您应该会看到预期的结果:
public void test1() {
try {
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newSingleThreadExecutor();
IntStream.range(0,1000).forEach(i->executor.submit( atomicInt::incrementAndGet ));
executor.shutdown();
// Wait a maximum of ~a million billion years
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
System.out.println("test1 result = "+ atomicInt.get());
}
catch (InterruptedException ex)
{
// Oh no!
}
}