原子地执行代码块 [英] executing block of code atomically

查看:29
本文介绍了原子地执行代码块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你会如何回答以下问题?

How would you answer the following question?

java 类的方法包含一段代码,该代码块必须是原子地执行.解释,使用适当的伪代码,你如何将确保此代码块以原子方式执行

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

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

Would I achieve this by making the method ..

public final AtomicInteger x = new AtomicInteger(0);

然后确保返回 get 语句:

then ensuring the get statement returned:

x.get()

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

and if I wanted to increment the value of x would I do this?

x.getAndIncrement();

推荐答案

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

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

I know of three valid definitions for atomic:

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

第一个可能是你教授的意思,而且很容易完成(见下文).

The first is probably what your professor meant, and it's pretty easy to accomplish (see below).

第二个(如 ACID 中的原子)可以近似.见下文.

The second (atomic as in ACID) can be approximated. See below.

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

The third simply cannot be guaranteed in Java - it doesn't provide access to the "critical sections" primitives required for uninterruptibility. Fortunately, the need for this is pretty much restricted to operating systems and device drivers.

同步中的原子

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

This is relatively straightforward: simply enclose your block of code in a synchronized block. I've shown it as a discrete block below, but there are other options:

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

ACID 中的原子

ACID 原子性没有通用的解决方案,但可以近似,也可以使用同步代码.为了做到这一点,动作的每个部分都必须是安全可逆的.

There's no general-case solution for ACID atomicity, but it can be approximated, also using synchronized code. In order to do this, each of the parts of the action must be safely reversible.

这就是我的处理方式:

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

For the sake of argument, assume there's a multipart action you need to do on an object we'll call exampleObj, that you have three actions to be performed which can be safely reversed, and that all access to example is synchronized on 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);
                }
            }
        }
    }

这篇关于原子地执行代码块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆