知识库--Creating Transaction in Java Using Akka(124)

来源:互联网 发布:淘宝上的体检中心在哪 编辑:程序博客网 时间:2024/05/29 16:38

For transactional support, extend the Atomic class and place code into the atomically() method of this class to wrap it into a transaction. To run transactional code, call the execute() method of the Atomic instance, like this:

return new Atomic<Object>() {    public Object atomically() {        //code to run in a transaction...        return resultObject;    }}.execute();

The thread that calls the execute() method runs the code within the atomically() method. However, the call is wrapped in a transaction if the caller is not already in a transaction.

//使用Akka :mutable Ref wrap immutable state

public class EnergySource{    private final long MAXLEVEL = 100;    final Ref<Long> level = new Ref<Long>(MAXLEVEL);    final Ref<Long> usageCount = new Ref<Long>(0L);    final Ref<Boolean> keepingRunning = new Ref<Boolean>(true);    private static final ScheduledExecutorService replenishTimer = Executors.newScheduledThreadPool(10);}
private EnergySource() {}private void init() {    replenishTimer.schedule(new Runnable() {        public void run() {            replenish();            if (keepRunning.get()) replenishTimer.schedule(this, 1, TimeUnit.SECONDS);        }    }, 1, TimeUnit.SECONDS);}public static EnergySource create() {    final EnergySource energySource = new EnergySource();    energySource.init();    return energySource;}public void stopEnergySource() { keepRunning.swap(false); }public long getUnitsAvailable() { return level.get(); }public long getUsageCount() { return usageCount.get(); }//useEnergy 需要事务保证修改两个变量public boolean useEnergy(final long units) {    return new Atomic<Boolean>() {        public Boolean atomically() {            long currentLevel = level.get();            if(units > 0 && currentLevel >= units) {                level.swap(currentLevel - units);                usageCount.swap(usageCount.get() + 1);                return true;            } else {                return false;            }        }    }.execute();}private void replenish() {    new Atomic() {        public Object atomically() {            long currentLevel = level.get();            if (currentLevel < MAXLEVEL) level.swap(currentLevel + 1);            return null;        }    }.execute();}

测试

public class UseEnergySource {    private static final EnergySource energySource = EnergySource.create();    public static void main(final String[] args)throws InterruptedException, ExecutionException {    System.out.println("Energy level at start: " +energySource.getUnitsAvailable());    List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();    for(int i = 0; i < 10; i++) {        tasks.add(new Callable<Object>() {            public Object call() {                for(int j = 0; j < 7; j++)                     energySource.useEnergy(1);                return null;            }        });    }    final ExecutorService service = Executors.newFixedThreadPool(10);     service.invokeAll(tasks);    System.out.println("Energy level at end: " + energySource.getUnitsAvailable());    System.out.println("Usage: " + energySource.getUsageCount());    energySource.stopEnergySource();    service.shutdown();    }}

//测试结果

Energy level at start: 100Energy level at end: 30Usage: 70

小结:
Akka quietly managed the transactions behind the scenes. Spend some time playing with that code and experiment with the transactions and threads.

0 0
原创粉丝点击