在看sun的代码时有许多经典实现,非常值得学习,下面是sun事件处理的经典实现,具体看代码:
public class MainLoop { private static MainLoop loop=null; private int pollRequests = 0; private MainLoop(){} public static MainLoop getInstance(){ if(loop==null){ loop=new MainLoop(); } return loop; } //自己实现 public BaseEvent retrieveEvent() { return null; } //自己实现 private boolean checkEvents() { return false; } public synchronized void startPolling() { pollRequests++; PollingThread.pollingThreadResume(); } public synchronized void stopPolling() { pollRequests--; if (pollRequests > 0) { return; } PollingThread.pollingThreadSuspend(); } public void pollEvents() { while (checkEvents()) { BaseEvent event = retrieveEvent(); if (event != null) { event.dispatch(); } } } }
mainloop为主控制类,想读取事件时,执行startPolling ,会开启一个pollingThread不停地pollEvent。
pollEvent不停地checkEvent,如果check到,就retrieveEvent,并把得到的event dispatch。
dispatch事件会把事件加入一队列等待执行事件的process。不想读事件时,直接stopPolling。需要自己根据情况
实现checkEvent和retrieveEvent,并实现自己的Event继承自BaseEvent。
BaseEvent.java
public abstract class BaseEvent { public void dispatch() { Dispatcher.enqueue(this); } abstract public void process(); }
PollingThread.java
public class PollingThread extends Thread { private static PollingThread instance = new PollingThread(); private static boolean suspended = true; private final int POLL_INTERVAL = 1000; public PollingThread() { } public static void pollingThreadSuspend() { synchronized (instance) { suspended = true; } } public static void pollingThreadResume() { try { instance.start(); } catch (IllegalThreadStateException e) { } synchronized (instance) { suspended = false; instance.notify(); } } public void run() { MainLoop loop = MainLoop.getInstance(); while (true) { try { synchronized (this) { if (suspended) { wait(); } } loop.pollEvents(); synchronized (this) { wait(POLL_INTERVAL); } } catch (InterruptedException e) { break; } } } }
Dispatcher.java
public class Dispatcher extends Thread { private static Dispatcher instance = new Dispatcher(); private static Vector<BaseEvent> events = new Vector<BaseEvent>(); public Dispatcher() { } public static void enqueue(BaseEvent event) { try { instance.start(); } catch (IllegalThreadStateException e) { } synchronized (events) { events.addElement(event); events.notify(); } } public void run() { while (true) { BaseEvent event = null; synchronized (events) { if (!events.isEmpty()) { event =events.firstElement(); events.removeElementAt(0); } else { try { events.wait(); } catch (InterruptedException e) { break; } } } if (event != null) { event.process(); } } } }