1. 观察者模式结合多线程实现获取线程执行结果
在多线程开发中,我们没办法获取线程执行完成后的结果,但是当我们利用观察者模式的时候我们就可以获取到多线程的执行结果
2.具体实现
假设目前有一批id需要查询并需要获得查询结果, 利用多线程结合设计模式实现
2.1 LifeCycleListener
public interface LifeCycleListener {
void onEvent(ObserverableRunnable.RunnableEvent event);
}
2.2 ObserverableRunnable
public abstract class ObserverableRunnable implements Runnable{
/**
* 监听这
*/
final protected LifeCycleListener listener;
public ObserverableRunnable(LifeCycleListener listener) {
this.listener = listener;
}
public void notifyChange(final RunnableEvent event) {
listener.onEvent(event);
}
public enum RunnableState {
RUNNING, ERROR, DONE;
}
/**
* 内部类尽量都是静态的,不然作为成员对象每次创建对象都会复制
*/
public static class RunnableEvent {
private final RunnableState state;
private final Thread thread;
private final Throwable cause;
public RunnableEvent(RunnableState state, Thread thread, Throwable cause) {
this.state = state;
this.thread = thread;
this.cause = cause;
}
public RunnableState getState() {
return state;
}
public Thread getThread() {
return thread;
}
public Throwable getCause() {
return cause;
}
}
}
2.3 ThreadLifeCycleObserver
package com.gy.observer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
/**
* 模拟当前类使用多线程需要去处理一批id,并拿到结果
* 1. 创建处理方法并通过ObserverableRunnable去执行任务
* 2. 当ObserverableRunnable吧任务执行完成后提醒当前类做完了
* 3. 拿到返回值处理
*/
public class ThreadLifeCycleObserver implements LifeCycleListener {
private Object LOCK = new Object();
private void concurrentQuery(List<Integer> ids) {
if (ids.size() == 0 && ids.isEmpty())
return;
ids.stream().forEach((id)->{
new Thread(new ObserverableRunnable(this) {
@Override
public void run() {
try {
notifyChange(new RunnableEvent(RunnableState.RUNNING, Thread.currentThread(), null));
System.out.printf("query for id = %s\n", id);
Thread.sleep(1000);
notifyChange(new RunnableEvent(RunnableState.DONE, Thread.currentThread(), null));
} catch (InterruptedException e) {
notifyChange(new RunnableEvent(RunnableState.ERROR, Thread.currentThread(), e));
}
}
}).start();
});
}
/**
* 这个方法可能是多个线程在回调所以需要使用同步锁
* @param event
*/
@Override
public void onEvent(ObserverableRunnable.RunnableEvent event) {
synchronized (LOCK) {
System.out.println(event.getThread().getName() + " == " + event.getState());
}
}
public static void main(String[] args) {
ThreadLifeCycleObserver threadLifeCycleObserver = new ThreadLifeCycleObserver();
threadLifeCycleObserver.concurrentQuery(Arrays.asList(1, 2, 3));
}
}