Java異步編程第1篇

   異步編程分爲兩種:JVM內部的異步編程和JVM之間的異步編程。本文主要思考JVM內部的異步(簡稱爲異步任務)。JVM之間的異步可以通過MQ等方式實現。

  1、異步任務是什麼?

  異步任務是由一系列的事件處理器(EventHandler)和Event(事件)組成,EventHandlers之間的通訊通過Event來實現。每一個EventHandler佔用一個線程(Thread)。

  2、異步任務需要提供哪些功能

      A、任務恢復機制:在任務被異常中斷的情況下,可以恢復任務。

      B、日誌追蹤機制:通過日誌信息,來判斷任務的執行情況,並對失敗的任務進行定位。

      C、元素鎖定機制:異步任務所涉及到的各種元素,有的需要鎖定,防止意外的操作,影響任務得進行。

  3、異步任務的粒度?

      粒度一:Event對應EventHandler。EventHandler響應傳過來的Event,但不改變Event的狀態

      粒度二:Event對應異步任務。Event在異步任務內部進行傳遞,內部的EventHandler可以更變Event的狀態,並傳遞到下一個節點。

  4、異步任務如何切分?

  異步任務有多個EventHandler組成,設計一個EventHandler的關鍵要素是快、全、少。

          A、快的含義是減少IO操作,爭取所有操作都在內存中完成。IO操作越多,處理時間越長,EventHandler越不穩定,任務完成得越慢。

          B、全的含義是每一個handler所處理的事情都是完整有意義的,不可分割的。用數據庫的話來說就是一個完整的事務。

          C、少的含義是一次完成一件事情。

  5、異步任務可以解決那些問題?

  異步任務可以解決【輪詢線程】的問題。過於複雜的輪詢線程是脆弱的,因爲有太多不可靠因素會導致線程死亡,就算線程的最外層加上try...catch,也僅僅是指標不治本。

  異步任務可以降低模塊之間的耦合。由於Handler之間是通過Event來觸發的,耦合程度降至爲【數據耦合】。

  6、異步任務需要依賴什麼?

  異步任務核心之一是事件派發器,派發器本質上是一個生產者消費者隊列,生產者負責發佈事件,消費者負責派發事件到處理器中。選擇的高性能隊列是核心任務,JDK自帶的Queue並不能滿足要求,可以選擇Disruptor框架。

     7、三種角色:

        A.event object(Event):就是事件產生時具體的“事件”,用於listener的相應的方法之中,作爲參數,一般存在與listerner的方法之中

        B.event source:具體的接受事件的實體,比如說,你點擊一個button,那麼button就是event source,這樣你必須使button對某些事件進行相應,你就需要註冊特定的listener。

       C.event listener(EventHandler):具體的對監聽的事件類,當有其對應的event object產生的時候,它就調用相應的方法,進行處理。


下面來看個實例,其組織結構圖如下:


Source.java源碼如下:

package com.event.test01;

import java.util.*;

public class Source {
	private Vector<ListenerDao> repository = new Vector<ListenerDao>();
	ListenerDao dl;

	public Source() {
	}

	public void addListener(ListenerDao dl) {
		repository.addElement(dl);
	}

	public void notifyEvent() {
		Enumeration<ListenerDao> enumx = repository.elements();
		while (enumx.hasMoreElements()) {
			dl = (ListenerDao) enumx.nextElement();
			dl.demoEvent(new Event(this)); // 通知所有監聽此事件的監聽者
		}
	}
}
Event.java源碼如下:

package com.event.test01;

import java.util.EventObject;

public class Event extends EventObject {
	Object obj;

	public Event(Object source) {
		super(source);
		obj = source;
	}

	public Object getSource() {// 獲得事件源的引用
		return obj;
	}
}
ListenerDao源碼如下:

package com.event.test01;

import java.util.EventListener;

public interface ListenerDao extends EventListener {
	public void demoEvent(Event dm);
}
如下源碼是ListenerDao的實現類:

package com.event.test01;

public class ListenerDaoImpl01 implements ListenerDao {
	public void demoEvent(Event de) {
		System.out.println("Inside listener1...");
	}
}
package com.event.test01;

public class ListenerDaoImpl02 implements ListenerDao {
	public void demoEvent(Event de) {
		System.out.println("Inside listener2...");
	}
}
最後編寫測試實例,如下:

package com.event.test01;

public class TestDemo {

	public TestDemo() {
		try {
			Source ds = new Source(); //事件源
			ListenerDaoImpl01 l1 = new ListenerDaoImpl01();
			ListenerDaoImpl02 l2 = new ListenerDaoImpl02();
			ds.addListener(l1);
			ds.addListener(l2);
			ds.addListener(new ListenerDao() {
				public void demoEvent(Event event) {
					System.out.println("Method come from 匿名類...");
				}
			});
			ds.notifyEvent(); // 事件源產生事件
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public static void main(String args[]) {
		new TestDemo();
	}
}

運行的結果如下:

Inside listener1...
Inside listener2...
Method come from 匿名類...













發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章