package com.github.sefler1987.javaworker.worker; import java.util.HashMap; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CopyOnWriteArrayList; /** * 工人 */ public class ConfigurableWorker implements Runnable, LifeCycle { //任务队列 private BlockingQueue<WorkerTask<?>> taskQueue = new ArrayBlockingQueue<WorkerTask<?>>(5); //有一个后台线程,在一直跑 private Thread thread; //工人的<事件->监听器列表>的映射. private HashMap<WorkerEvent, CopyOnWriteArrayList<WorkerListener>> listenerMap; //要怎么处理任务. 线性,还是MapReduce? 一个工人有一个任务处理器 private TaskProcessor taskProcessor; //只有初始化完毕,才可以工作 private volatile boolean initiated = false; //工人id private String workerID; public ConfigurableWorker(String workerID) { this.workerID = workerID; } @Override public void start() { if (!initiated) { init(); } thread.start(); } @Override public void init() { if (initiated) return; if (taskProcessor == null) throw new IllegalStateException("Task Processor must be set first"); thread = new Thread(this); thread.setDaemon(true); //初始化时,工人会对一个事件会有多个监听事件 listenerMap = new HashMap<WorkerEvent, CopyOnWriteArrayList<WorkerListener>>(); initiated = true; } @Override public void stop() { thread.interrupt(); } // 给工人添加任务. 任务用队列来保存. 任何需要执行一定时间的任务最好放在队列里(生产). 并用一个后台线程来消费队列里的任务 public String addTask(WorkerTask<?> task) { if (!initiated) { init(); } try { taskQueue.put(task); } catch (InterruptedException e) { thread.interrupt(); } //放入队列后, 立即返回. 不需要等待任务执行. return task.getTaskID(); } // 给工人添加任务, 由于任务可能长时间运行, 所以不能等待工人完成一个任务,再执行接下来的任务. // 所以在任务完成的时候, 需要能够通知给调用者, 说工人完成任务了. 任务有两种执行结果: 执行成功,执行失败 // 这都属于任务执行的事件状态. 当任务到达这两种状态的一种, 都应该能够触发相应的事件. // 使用监听器来完成事件的通知. // 给工人添加监听器. 在开始工作前,要指定对某一类的事件注册监听器 public synchronized void addListener(WorkerListener listener) { if (!initiated) { init(); } List<WorkerEvent> intrestEvents = listener.intrests(); for (WorkerEvent event : intrestEvents) { CopyOnWriteArrayList<WorkerListener> listeners = listenerMap.get(event); //第一个监听器,创建一个列表,并将其加入列表中 if (listeners == null) { listeners = new CopyOnWriteArrayList<WorkerListener>(); } //将当前要注册的监听器,加入到这个时间的监听器列表中. listeners.add(listener); listenerMap.put(event, listeners); } } // 工人的后台线程, 工作啦, 啦啦啦....啦啦啦... 啦啦啦 @Override public void run() { try { for (;;) { //从队列中获取任务 WorkerTask<?> task = taskQueue.take(); //使用任务处理器执行任务, 任务的执行是顺序的! taskProcessor.process(task); //任务完成后,触发"任务执行完成"的事件 if (task.isDone()) { fireEvent(WorkerEvent.TASK_COMPLETE, task); //完成当前任务后,继续for循环. 看看队列中还有没有要执行的任务 continue; } //任务没有完成,触发"任务执行失败"的事件 fireEvent(WorkerEvent.TASK_FAILED, task); } } catch (InterruptedException e) { System.out.println("Worker mission canceled, remaining task size: " + taskQueue.size()); return; } } // Got Event! DO DO DO THE FUCKING DEAD WORK! // 当给工人注册的事件发生时, 触发监听器的调用. public void fireEvent(WorkerEvent event, Object... args) { CopyOnWriteArrayList<WorkerListener> listeners = listenerMap.get(event); //这个事件没有监听器, 不做任何事 if (listeners == null) return; //对在这个事件上的每个监听器,进行回调 for (WorkerListener listener : listeners) { //回调. 自定义的监听器实现类需要对不同的事件做不同的响应. listener.onEvent(event, args); } } public TaskProcessor getTaskProcessor() { return taskProcessor; } public void setTaskProcessor(TaskProcessor taskProcessor) { this.taskProcessor = taskProcessor; } public String getWorkerID() { return workerID; } }