@StateMachine static interface LockingStateMachine { @StateSet static interface States { @Initial @Function(transition = LockingStateMachine.Transitions.Start.class, value = Started.class) static interface Created {} @Functions({ @Function(transition = LockingStateMachine.Transitions.Stop.class, value = Stopped.class), @Function(transition = LockingStateMachine.Transitions.Cancel.class, value = Canceled.class) }) static interface Started {} @End static interface Stopped {} @End static interface Canceled {} } @TransitionSet static interface Transitions { static interface Start {} static interface Stop {} static interface Cancel {} } } static interface ILockingReactiveObject { public abstract int getCounter(); public abstract void start(); public abstract void stop(); public abstract void cancel(); }
public static class SimpleLock implements LifecycleLockStrategry { private static Logger logger = Logger.getLogger("Lifecycle Framework"); private static volatile int depth = 0; private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); @Override public void lockRead(Object reactiveObject) { logLockingMethod(reactiveObject, "lockRead: "); lock.readLock().lock(); depth++; } private void logLockingMethod(Object reactiveObject, String methodName) { final StringBuilder builder = getIndent(); builder.append(methodName + reactiveObject); logger.fine(builder.toString()); } private StringBuilder getIndent() { StringBuilder builder = new StringBuilder(); for ( int i = 0; i klass) throws Throwable { final ExecutorService executorService = Executors.newFixedThreadPool(7); for ( int i = 0; i c1 = new Callable() { @Override public LifecycleException call() throws Exception { try { object.stop(); return null; } catch (LifecycleException e) { return e; } } }; Callable c2 = new Callable() { @Override public LifecycleException call() throws Exception { try { object.cancel(); return null; } catch (LifecycleException e) { return e; } } }; if ( i % 2 == 0 ) { Callable temp = c1; c1 = c2; c2 = temp; } final Future f1 = executorService.submit(c1); final Future f2 = executorService.submit(c2); final Callable c3 = new Callable() { @Override public Exception call() throws Exception { try { final LifecycleException e1 = f1.get(); final LifecycleException e2 = f2.get(); assertFalse(( null != e1 && null != e2 ) || ( null == e1 && null == e2 )); final LifecycleException e = null != e1 ? e1 : e2; System.out.println(e.toString()); assertEquals(LifecycleCommonErrors.ILLEGAL_TRANSITION_ON_STATE, e.getErrorCode()); assertEquals(2, object.getCounter()); return null; } catch (Exception e) { return e; } } }; final Future f3 = executorService.submit(c3); if ( null != f3.get() ) { fail(f3.get().getMessage()); } } }
日志截屏如下(请点击放大)
日志解释:
执行过程中的加(获取)写锁和解(释放)写锁的过程
[FINE]: Found Intercept Point: class net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject.start( )
[FINE]: Intercepting....instatiating InterceptContext ...
[FINE]: Intercepting....InterceptorController is doing exec ...
[FINE]: Intercepting....instantiating LifecycleInterceptor
[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @preExec
[FINE]: lockWrite: net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@62b9f149
[FINE]: intercepting [net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@62b9f149]
from state: [Created]
[FINE]: Step 1. start validating State [Created]
[FINE]: Step 2. start validating transition: [Start] on state: [Created]
[FINE]: Step 3. start validating inbound relation constraint is next state is predictable before method invocation.
[FINE]: Step 4. start callback before state change from : Created => to : Started
[FINE]: intercepting with: net.madz.bcel.intercept.CallableInterceptor @intercept
[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @postExec
[FINE]: Step 5. start validating inbound relation constraint is next state after method invocation.
[FINE]: Step 6. Set next state to reactiveObject.
[FINE]: Step 6. ReactiveObject is tranisited to state: [Started]
[FINE]: Step 7. Start Callback after state change from : Created => to : Started
[FINE]: unlockWrite: net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@62b9f149
[FINE]: Step 8. Start fire state change event.
[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @cleanup
[FINE]: Intercepting....LifecycleInterceptor is doing cleanup ...
并发执行同步过程日志
//线程一开始获取写锁
[FINE]: lockWrite: net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@31c1fb39
//线程二开始获取写锁
[FINE]: lockWrite: net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@31c1fb39
//线程一得到写锁并继续执行生命周期引擎
[FINE]: intercepting [net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@31c1fb39]
from state: [Started]
[FINE]: Step 1. start validating State [Started]
[FINE]: Step 2. start validating transition: [Stop] on state: [Started]
[FINE]: Step 3. start validating inbound relation constraint is next state is predictable before method invocation.
[FINE]: Step 4. start callback before state change from : Started => to : Stopped
[FINE]: intercepting with: net.madz.bcel.intercept.CallableInterceptor @intercept
[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @postExec
[FINE]: Step 5. start validating inbound relation constraint is next state after method invocation.
[FINE]: Step 6. Set next state to reactiveObject.
[FINE]: Step 6. ReactiveObject is tranisited to state: [Stopped]
[FINE]: Step 7. Start Callback after state change from : Started => to : Stopped
//第一线程执行完Transition开始解写锁
[FINE]: unlockWrite: net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@31c1fb39
[FINE]: Step 8. Start fire state change event.
//线程二得到写锁开始执行引擎
[FINE]: intercepting [net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@31c1fb39]
from state: [Stopped] //此时状态已经变为Stopped,线程一导致的变化至此已被线程二看见
[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @cleanup
[FINE]: Step 1. start validating State [Stopped]
[FINE]: Intercepting....LifecycleInterceptor is doing cleanup ...
[FINE]: Step 2. start validating transition: [Cancel] on state: [Stopped]
[FINE]: intercepting with :net.madz.bcel.intercept.LifecycleInterceptor @cleanup
[FINE]: Intercepting....LifecycleInterceptor is doing cleanup ...
[SEVERE]: ReactiveObject: [net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@31c1fb39] was failed to transit from state: [Stopped] to state: [(Had Not Been Evaluated)] with following error:
//由于在执行过程中另一线程导致状态发生变化,而使得本线程的Transition不合法
[SEVERE]: Illegal Request Found on object net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@31c1fb39: Transition Cancel is not allowed while object is on Stopped state.
//线程二Transition失败后开始释放写[FINE]: unlockWrite: net.madz.lifecycle.engine.LifecycleLockTestMetadata$SimpleLockingReactiveObject@31c1fb39
前文:生命周期组件框架:关系型状态机服务
相关推荐
数据库思维导图——并发控制 并发控制 多事务执行方式 (1)事务串行执行 每个时刻只有一个事务运行,其他事务必须等到这个事务结束以后方能运行 不能充分利用系统资源,发挥数据库共享资源的特点 (2)交叉并发方式...
《操作系统——并发与分布式软件设计》((英国)Jean Bacon & (英国)Tim harris)清晰版[DJVU]
服装设计作品在线展销系统这篇论文是独创,里面涵盖了网上在线购物所运用到的流行元素:高并发,分布式思想以及maven管理机制等一系列电商所运用的技术理念。
SQLite是文件级别的数据库,其锁也是文件级别的:多个线程可以同时读,但是同时只能有一个线程写。Android提供了SqliteOpenHelper类,加入Java的锁机制以便调用。但在C#中未提供类似功能。 作者利用读写锁...
Skynet是一个开源并发框架,它为了简悦的第一个MMORPG服务器所编写,但应用领域不限于网络游戏。Skynet的核心部分不到3000行C代码,利用actor模式充分利用单机多核的优势,尽量将业务逻辑进行并行处理。相对于Erlang...
面试官:Zookeeper怎么解决读写、双写并发不一致问题,以及共享锁的实现原理?.doc
net并发数据结构读写锁
节省半导体测试时间成本的新方法——并发测试.pdf
现在的Web系统面对的并发连接数在近几年呈现指数增长,高并发成为了一种常态,给Web系统带来不小的挑战。一味地通过增加机器来解决并发量的增长,成本是非常高昂的。结合技术优化方案,才是更有效的解决方法。徐汉彬...
操作系统原理 [操作系统——并发与分布式软件设计].(英国)Jean.Bacon.清晰版.pdf
第3章 Go语言并发组件 47 goroutine 47 sync包 58 WaitGroup 58 互斥锁和读写锁 60 cond 64 once 69 池 71 channel 76 select 语句 92 GOMAXPROCS控制 97 小结 98 第4章 Go语言的并发模式 99 约束 99 for-select循环...
关于java中线程的一些基础知识详解文档和知识点,内容详细,通俗易懂,非常适合当接触线程知识的同学,以及复习线程理论知识人员
6.2.4 Executor的生命周期 6.2.5 延迟任务与周期任务 6.3 找出可利用的并行性 6.3.1 示例:串行的页面渲染器 6.3.2 携带结果的任务Callable与Future 6.3.3 示例:使用Future实现页面渲染器 6.3.4 在异构任务...
优化nginx大并发——轻松应对上万并发访问 优化Nginx突破十万并发 搭建web nginx服务器是网站开发必不可少的技能,学好了,给公司省大钱
在本节,我们对Go语言所提供的与锁有关的API进行说明。这包括了互斥锁和读写锁。我们在第6章描述过互斥锁,但却没有提到过读写锁。这两种锁对于传统的并发程序来说都是非常常用和重要的。 一、互斥锁 互斥锁是传统的...
海量并发微服务框架设计
6.2.4 Executor的生命周期 6.2.5 延迟任务与周期任务 6.3 找出可利用的并行性 6.3.1 示例:串行的页面渲染器 6.3.2 携带结果的任务Callable与Future 6.3.3 示例:使用Future实现页面渲染器 6.3.4 在异构任务...
Linux设备驱动——中断、并发请求及周期性事件处理,描述
大厂Java面试真题分为Java、算法、操作系统、网络、面向对象、数据库、Java、系统设计、工具,本资料属于Java并发面试专题