Java并发编程实战~Guarded Suspension模式
Guarded Suspension 模式
????????比如,項(xiàng)目組團(tuán)建要外出聚餐,我們提前預(yù)訂了一個(gè)包間,然后興沖沖地奔過(guò)去,到那兒后大堂經(jīng)理看了一眼包間,發(fā)現(xiàn)服務(wù)員正在收拾,就會(huì)告訴我們:“您預(yù)訂的包間服務(wù)員正在收拾,請(qǐng)您稍等片刻。”過(guò)了一會(huì),大堂經(jīng)理發(fā)現(xiàn)包間已經(jīng)收拾完了,于是馬上帶我們?nèi)グg就餐。
????????那我們來(lái)看看現(xiàn)實(shí)世界里是如何解決這類(lèi)問(wèn)題的呢?現(xiàn)實(shí)世界里大堂經(jīng)理這個(gè)角色很重要,我們是否等待,完全是由他來(lái)協(xié)調(diào)的。通過(guò)類(lèi)比,相信你也一定有思路了:我們的程序里,也需要這樣一個(gè)大堂經(jīng)理。的確是這樣,那程序世界里的大堂經(jīng)理該如何設(shè)計(jì)呢?其實(shí)設(shè)計(jì)方案前人早就搞定了,而且還將其總結(jié)成了一個(gè)設(shè)計(jì)模式:Guarded Suspension。所謂Guarded Suspension,直譯過(guò)來(lái)就是“保護(hù)性地暫停”。
class GuardedObject<T>{// 受保護(hù)的對(duì)象private T obj;final Lock lock = new ReentrantLock();final Condition done = lock.newCondition();final int timeout=1;// 獲取受保護(hù)對(duì)象 public T get(Predicate<T> p) {lock.lock();try {//MESA 管程推薦寫(xiě)法while(!p.test(obj)){done.await(timeout, TimeUnit.SECONDS);}}catch(InterruptedException e){throw new RuntimeException(e);}finally{lock.unlock();}// 返回非空的受保護(hù)對(duì)象return obj;}// 事件通知方法public void onChanged(T obj) {lock.lock();try {this.obj = obj;done.signalAll();} finally {lock.unlock();}} }擴(kuò)展 Guarded Suspension 模式
????????每個(gè)發(fā)送到 MQ 的消息,都有一個(gè)唯一性的屬性 id,所以我們可以維護(hù)一個(gè) MQ 消息 id 和GuardedObject 對(duì)象實(shí)例的關(guān)系,這個(gè)關(guān)系可以類(lèi)比大堂經(jīng)理大腦里維護(hù)的包間和就餐人的關(guān)系。
class GuardedObject<T>{// 受保護(hù)的對(duì)象T obj;final Lock lock = new ReentrantLock();final Condition done = lock.newCondition();final int timeout=2;// 保存所有 GuardedObjectfinal static Map<Object, GuardedObject> gos = new ConcurrentHashMap<>();// 靜態(tài)方法創(chuàng)建 GuardedObjectpublic static <K> GuardedObject create(K key){GuardedObject go=new GuardedObject();gos.put(key, go);return go;}public static <K, T> void fireEvent(K key, T obj){GuardedObject go=gos.remove(key);if (go != null){go.onChanged(obj);}}// 獲取受保護(hù)對(duì)象 public T get(Predicate<T> p) {lock.lock();try {//MESA 管程推薦寫(xiě)法while(!p.test(obj)){done.await(timeout, TimeUnit.SECONDS);}}catch(InterruptedException e){throw new RuntimeException(e);}finally{lock.unlock();}// 返回非空的受保護(hù)對(duì)象return obj;}// 事件通知方法void onChanged(T obj) {lock.lock();try {this.obj = obj;done.signalAll();} finally {lock.unlock();}} }利用擴(kuò)展后的 GuardedObject 來(lái)解決消息反饋后處理很簡(jiǎn)單了
// 處理瀏覽器發(fā)來(lái)的請(qǐng)求 Respond handleWebReq(){int id= 序號(hào)生成器.get();// 創(chuàng)建一消息Message msg1 = new Message(id,"{...}");// 創(chuàng)建 GuardedObject 實(shí)例GuardedObject<Message> go= GuardedObject.create(id); // 發(fā)送消息send(msg1);// 等待 MQ 消息Message r = go.get(t->t != null); }void onMessage(Message msg){// 喚醒等待的線程GuardedObject.fireEvent(msg.id, msg); }總結(jié)
以上是生活随笔為你收集整理的Java并发编程实战~Guarded Suspension模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring Data JPA 从入门到
- 下一篇: Java加密与解密的艺术~Securit