多线程观察者模式
定义观察者事件公共接口
package com.ln.concurrent.chapter4;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter4
* @Name:LifeCycleListener
* @Author:linianest
* @CreateTime:2021/1/1 17:30
* @version:1.0
* @Description TODO: 定义观察者公共接口
*/
public interface LifeCycleListener {
// todo 观察者观察线程状态
void onEvent(ObservableRunnable.RunnableEvent event);
}
定义观察者线程接口
package com.ln.concurrent.chapter4;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter4
* @version: 1.0
*/
/**
*@ClassName:ObservableRunnable
*@Author:linianest
*@CreateTime:2020/3/23 12:03
*@version:1.0
*@Description TODO: 可供观察的线程Runnable,提供线程的事件、状态、异常信息,反馈给观察者的onEvent抽象方法
*/
public abstract class ObservableRunnable implements Runnable {
// listener是抽象类的观察者
final protected LifeCycleListener listener;
public ObservableRunnable(final LifeCycleListener listener){
this.listener = listener;
}
// 事件源
protected 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;
/**
* @param state 线程状态
* @param thread 线程
* @param 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;
}
}
}
实现观察者事件公共接口
package com.ln.concurrent.chapter4;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter4
* @version: 1.0
*/
import java.util.List;
/**
* @ClassName:ThreadLifeCycleObserver
* @Author:linianest
* @CreateTime:2020/3/23 12:12
* @version:1.0
* @Description TODO: 实现多线程观察者实现接口,当有线程状态发生改变时,反馈给onEvent方法
*/
public class ThreadLifeCycleObserver implements LifeCycleListener {
private final Object LOCK = new Object();
/**
* 当事件队列有事件时,每个事件都会启动一个线程去获取事件信息
*
* @param ids
*/
public void concurrentQuery(List<String> ids) {
if (ids == null || ids.isEmpty())
return;
/**
* todo this表示当前类是观察者
* notifyChange 方法时runnable接口的方法,提供事件状态信息
*/
ids.stream().forEach(id -> new Thread(new ObservableRunnable(this) {
@Override
public void run() {
try {
notifyChange(new RunnableEvent(RunnableState.RUNNING, Thread.currentThread(), null));
System.out.println("query for the id " + id);
Thread.sleep(1_000L);
notifyChange(new RunnableEvent(RunnableState.DONE, Thread.currentThread(), null));
} catch (Exception e) {
notifyChange(new RunnableEvent(RunnableState.ERROR, Thread.currentThread(), e));
}
}
}, id).start());
}
/**
* Runnable 回调事件
*
* @param event
*/
@Override
public void onEvent(ObservableRunnable.RunnableEvent event) {
synchronized (LOCK) {
System.out.println("The runnable [" + event.getThread().getName() + "] data changed and state is [" + event.getState() + "]");
if (event.getCause() != null) {
System.out.println("The runnable [" + event.getThread().getName() + "] process failed.");
event.getCause().printStackTrace();
}
}
}
}
测试多线程观察者
package com.ln.concurrent.chapter4;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.chapter4
* @version: 1.0
*/
import java.util.Arrays;
/**
*@ClassName:ThreadLifeCycleClient
*@Author:linianest
*@CreateTime:2020/3/23 12:43
*@version:1.0
*@Description TODO: 多线程观察者模式
*/
public class ThreadLifeCycleClient {
public static void main(String[] args) {
new ThreadLifeCycleObserver().concurrentQuery(Arrays.asList("1","2"));
}
}