Java 使用AtomicInteger和Synchronized提供不同结果的ExecutorService 下面是代码-AtomicInteger 上述代码的输出: 同步分组码的输出 2个输入的运行:池-1-线程-2 1个已输入的运行:池-1-线程-1 2正在执行:池-1-线程-2 2正在执行:池-1-线程-1 2已完成执行:池-1-线程-2 2已完成执行:池-1-线程-1 3个输入运行:池-1-线程-2 3执行:池1线程2 3已完成执行:池-1-线程-2 问题? 为什么产出有差异 为什么原子整数会从1增加到2 如何使用atomicinteger实现同步输出 同时使用volatile和atomic有什么好处或用途
Java 使用AtomicInteger和Synchronized提供不同结果的ExecutorService 下面是代码-AtomicInteger 上述代码的输出: 同步分组码的输出 2个输入的运行:池-1-线程-2 1个已输入的运行:池-1-线程-1 2正在执行:池-1-线程-2 2正在执行:池-1-线程-1 2已完成执行:池-1-线程-2 2已完成执行:池-1-线程-1 3个输入运行:池-1-线程-2 3执行:池1线程2 3已完成执行:池-1-线程-2 问题? 为什么产出有差异 为什么原子整数会从1增加到2 如何使用atomicinteger实现同步输出 同时使用volatile和atomic有什么好处或用途,java,multithreading,concurrency,executorservice,compare-and-swap,Java,Multithreading,Concurrency,Executorservice,Compare And Swap,AtomicInteger使用引擎盖下的volatile字段。这样做的目的是确保所有读卡器(其他线程)使用最新的值。在第二种情况下使用简单的int时,字段不是volatile,因此您看到的1来自过时的值 通过使用volatile关键字,您应该能够获得类似的结果 另一种方法是在继续前进之前,使用闸门确保满足条件。这可以通过倒计时闩锁实现,例如(还有其他方法):原子整数使用引擎盖下的volatile字段。这样做的目的是确保所有读卡器(其他线程)使用最新的值。在第二种情况下使用简单的int时,字段不是
AtomicInteger
使用引擎盖下的volatile
字段。这样做的目的是确保所有读卡器(其他线程)使用最新的值。在第二种情况下使用简单的int
时,字段不是volatile
,因此您看到的1
来自过时的值
通过使用volatile
关键字,您应该能够获得类似的结果
另一种方法是在继续前进之前,使用闸门确保满足条件。这可以通过
倒计时闩锁
实现,例如(还有其他方法):原子整数使用引擎盖下的volatile
字段。这样做的目的是确保所有读卡器(其他线程)使用最新的值。在第二种情况下使用简单的int
时,字段不是volatile
,因此您看到的1
来自过时的值
通过使用volatile
关键字,您应该能够获得类似的结果
另一种方法是在继续前进之前,使用闸门确保满足条件。例如,这可以通过
倒计时闩锁
实现(也有其他方法):期望值为count保持执行run方法的线程的计数。顺便说一句,在第二个示例中,您在synchornized块中增加变量,但在读取时,您没有同步,这可能会产生可见性问题。期望值为count保持执行run方法的线程的计数。顺便说一句,在第二个示例中示例:在synchornized块中递增变量,但读取时不进行同步,这可能会产生可见性问题。使用atomicinteger,为什么计数会从0递增到2而不是1?如果运行足够多的时间,您会发现它先变为1的情况。当您首先看到2时,这只是意味着两个线程在打印任何内容之前都执行了增量。使用atomicinteger为什么计数会从0增加到2而不是1?如果您运行它足够多的时间,您会发现它首先变为1的情况。当您首先看到2时,这意味着两个线程在打印任何内容之前都执行了增量。
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-1
2 Enterd Run of: pool-1-thread-2
2 Executing: pool-1-thread-2
2 Executing: pool-1-thread-1
2 Completed Executing: pool-1-thread-1
2 Completed Executing: pool-1-thread-2
3 Enterd Run of: pool-1-thread-1
3 Executing: pool-1-thread-1
3 Completed Executing: pool-1-thread-1
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());
}
}
2 Enterd Run of: pool-1-thread-2
1 Enterd Run of: pool-1-thread-1
2 Executing: pool-1-thread-2
2 Executing: pool-1-thread-1
2 Completed Executing: pool-1-thread-2
2 Completed Executing: pool-1-thread-1
3 Enterd Run of: pool-1-thread-2
3 Executing: pool-1-thread-2
3 Completed Executing: pool-1-thread-2