你会如何回答下面的问题?
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
的三个有效定义:
- 同步中的原子性:一次只能有一个线程执行代码;
- 在 ACID 中是原子的:所有的 Action / block 都发生,或者一个都不发生;
- 不可中断的原子性:一旦 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/