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产生的时候,它就调用相应的方法,进行处理。


下面来看个实例,其组织结构图如下:

Java异步编程第1篇_第1张图片

Source.java源码如下:

package com.event.test01;

import java.util.*;

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

	public Source() {
	}

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

	public void notifyEvent() {
		Enumeration 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 匿名类...













你可能感兴趣的:(Java异步编程第1篇)