java - 原子地执行代码块

标签 java thread-safety atomic

你会如何回答下面的问题?

A method of a java class contains a block of code that must be executed atomically. Explain, using appropriate pseudo-code, how you would ensure that this block of code is executed atomically

我会通过制作方法来实现这个吗..

public final AtomicInteger x = new AtomicInteger(0);

然后确保返回 get 语句:

x.get()

如果我想增加 x 的值,我会这样做吗?

x.getAndIncrement();

最佳答案

答案取决于你对“原子”的定义

我知道 atomic 的三个有效定义:

  1. 同步中的原子性:一次只能有一个线程执行代码;
  2. 在 ACID 中是原子的:所有的 Action / block 都发生,或者一个都不发生;
  3. 不可中断的原子性:一旦 block 开始,它就不能被中断,即使是通过任务切换也是如此。

第一个可能是您教授的意思,它很容易实现(见下文)。

第二个(在 ACID 中是原子的)可以近似计算。见下文。

第三个在 Java 中根本无法保证——它不提供对不间断性所需的“关键部分”原语的访问。幸运的是,对此的需求几乎仅限于操作系统和设备驱动程序。

同步中的原子

这相对简单:只需将您的代码块包含在一个同步块(synchronized block)中。我在下面将其显示为一个离散 block ,但还有其他选项:

public void doSomethingQuasiAtomic() {
   synchronized (exampleLock) {
      // Your code block goes here. 
      // Only one thread will ever be in this block at a time.
      ...
   }
}

在 ACID 中是原子的

ACID 原子性没有一般情况下的解决方案,但它可以近似,也可以使用同步代码。为了做到这一点, Action 的每个部分都必须是安全可逆的。

这就是我的处理方式:

为了论证,假设您需要对我们称为 exampleObj 的对象执行多部分操作,您要执行三个操作,这三个操作可以安全 反转,所有对 example 的访问都在 exampleLock 上同步。


    synchronized(exampleLock) {
        boolean actionOneDone=false;
        boolean actionTwoDone=false;
        boolean actionThreeDone=false;
        try {
            actionOneDone=doActionOne(exampleObj);    // or perhaps exampleObj.doActionOne();
            if(actionOneDone) actionTwoDone=doActionTwo(exampleObj);
            if(actionTwoDone) actionThreeDone=doActionThree(exampleObj);
        } catch (Exception ex) {
            // Whatever seems appropriate here.
        } finally { 
            if (! (actionOneDone && actionTwoDone && actionThreeDone)) {
                /* At least one part failed.  Back out the completed actions in reverse order.  
                 * Note that we never need to reverse action three since if it completed, so did the others.
                 */
                if (actionTwoDone) {
                   reverseActionTwo(exampleObj);    // or perhaps exampleObj.reverseActionTwo();
                }
                if (actionOneDone) {
                   reverseActionOne(exampleObj);
                }
            }
        }
    }

关于java - 原子地执行代码块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16902224/

相关文章:

java - 在 POI 中合并 excel 输出中的单元格

multithreading - Delphi线程最佳实践

这可以原子执行吗?

c - C 中的原子读取

java - 将通知点击数据发送到子 Activity

java - 如何在 JAVA 中的 Rijndael 加密等效项中获得正确的 KEY 和 IV

multithreading - Gdiplus 线程安全吗?

java - 来自多个线程的数组的非锁定交互(在 Java 中)

c++ - 可能同时将 *same* 值写入一个整数。我需要一个原子变量吗?

java - Akka远程actor部署文档错误