ger*_*tom 10 java atomic thread-safety
你会如何回答以下问题?
java类的方法包含必须以原子方式执行的代码块.使用适当的伪代码解释如何确保以原子方式执行此代码块
我会通过制作方法来实现这一点吗?
public final AtomicInteger x = new AtomicInteger(0);
Run Code Online (Sandbox Code Playgroud)
然后确保返回get语句:
x.get()
Run Code Online (Sandbox Code Playgroud)
如果我想增加x的值,我会这样做吗?
x.getAndIncrement();
Run Code Online (Sandbox Code Playgroud)
CPe*_*ins 45
答案取决于你对"原子"的定义
我知道三个有效的定义atomic:
第一个可能是你的教授的意思,而且很容易实现(见下文).
第二个(ACID中的原子)可以近似.见下文.
第三个简单地无法在Java中得到保证 - 它不提供对不间断性所需的"关键部分"原语的访问.幸运的是,对此的需求几乎仅限于操作系统和设备驱动程序.
同步中的原子
这是相对简单的:只需将代码块包含在同步块中即可.我已将它显示为下面的离散块,但还有其他选项:
public void doSomethingQuasiAtomic() {
synchronized (exampleLock) {
// Your code block goes here.
// Only one thread will ever be in this block at a time.
...
}
}
Run Code Online (Sandbox Code Playgroud)
ACID中的原子
ACID原子性没有通用的解决方案,但也可以使用同步代码进行近似.为了做到这一点,动作的每个部分必须是安全可逆的.
这就是我接近它的方式:
为了论证,假设您需要对我们要调用的对象执行多部分操作,您需要执行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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15565 次 |
| 最近记录: |