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));
}
}