答案取决于您对“原子”的定义
我知道以下三个有效定义
atomic:
- 与同步中的原子相同:一次只能有一个线程执行代码;
- 像ACID中那样是原子的:所有动作/阻止都发生,或没有动作;
- 原子不可中断:一旦块开始,就不能被中断,即使通过任务切换也是如此。
第一个可能是您的教授的意思,并且很容易实现(请参见下文)。
第二个(如ACID中的原子)可以近似。见下文。
用Java不能完全保证第三个-它不提供对不中断所需的“关键部分”原语的访问。幸运的是,对此的需求几乎仅限于操作系统和设备驱动程序。
原子同步
这是相对简单的:只需将代码块包含在同步块中即可。我在下面将其显示为离散块,但还有其他选择:
public void doSomethingQuasiAtomic() { synchronized (exampleLock) { // Your pre block goes here. // only one thread will ever be in this block at a time. ... }}像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)) { if (actionTwoDone) { reverseActionTwo(exampleObj); // or perhaps exampleObj.reverseActionTwo(); } if (actionOneDone) { reverseActionOne(exampleObj); } } } }


