gpt4 book ai didi

java - ExecutorService 与 AtomicInteger 和 Synchronized 给出不同的结果

转载 作者:太空宇宙 更新时间:2023-11-04 09:07:47 25 4
gpt4 key购买 nike

以下是代码 - AtomicInteger

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class ExecutorExample1 {
public static void main(String[] args) {
ExecutorService executorService= Executors.newFixedThreadPool(2);
executorService.execute(new MyTask());
executorService.execute(new MyTask());
executorService.execute(new MyTask());
executorService.shutdown();
}
}

class MyTask implements Runnable{
private static AtomicInteger count = new AtomicInteger(0);
@Override
public void run() {
try {
count.addAndGet(1);
task();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private void task()throws InterruptedException{
System.out.println(count + " Enterd Run of: " + Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println(count + " Executing: " + Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println(count + " Completed Executing: " + Thread.currentThread().getName());
}
}

上述代码的输出:

2 Enterd Run of: pool-1-thread-12 Enterd Run of: pool-1-thread-22 Executing: pool-1-thread-22 Executing: pool-1-thread-12 Completed Executing: pool-1-thread-12 Completed Executing: pool-1-thread-23 Enterd Run of: pool-1-thread-13 Executing: pool-1-thread-13 Completed Executing: pool-1-thread-1

Same code replacing AtomicInteger with int and synchronized block

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class ExecutorExample1 {
public static void main(String[] args) {
ExecutorService executorService= Executors.newFixedThreadPool(2);
executorService.execute(new MyTask());
executorService.execute(new MyTask());
executorService.execute(new MyTask());
executorService.shutdown();
}
}

class MyTask implements Runnable{
//private static AtomicInteger count = new AtomicInteger(0);
private static int count = 0;
@Override
public void run() {
try {
//count.addAndGet(1);
synchronized (MyTask.class){
count+=1;
}
task();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private void task()throws InterruptedException{
System.out.println(count + " Enterd Run of: " + Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println(count + " Executing: " + Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println(count + " Completed Executing: " + Thread.currentThread().getName());
}
}

同步块(synchronized block)代码的输出

2 Enterd Run of: pool-1-thread-21 Enterd Run of: pool-1-thread-12 Executing: pool-1-thread-22 Executing: pool-1-thread-12 Completed Executing: pool-1-thread-22 Completed Executing: pool-1-thread-13 Enterd Run of: pool-1-thread-23 Executing: pool-1-thread-23 Completed Executing: pool-1-thread-2

问题?

  1. 为什么输出存在差异?
  2. 为什么原子整数从 1 增加到 2。
  3. 如何使用atomicinteger实现同步输出。
  4. 同时使用 volatile 和atomic 有什么好处或用途?

最佳答案

AtomicInteger 在底层使用 volatile 字段。这样做的作用是确保所有读取器(其他线程)都使用最新的值。在第二种情况下使用简单的 int 时,您的字段不是 volatile ,因此您看到的 1 来自过时的值。

通过使用 volatile 关键字,您应该能够获得类似的结果。

另一种方法是使用门来确保在继续前进之前满足条件。例如,这可以通过 CountDownLatch 来实现(还有其他方法):https://www.baeldung.com/java-countdown-latch

关于java - ExecutorService 与 AtomicInteger 和 Synchronized 给出不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60025298/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com