public interface LifeCycleListener {
void onEvent(AbservableRunnable.RunnableEvent event);
}
public enum RunnableState {
RUNNING, ERROR, DONE
}
public abstract class AbservableRunnable implements Runnable{
final protected LifeCycleListener listener;
public AbservableRunnable(LifeCycleListener listener) {
this.listener = listener;
}
protected void notifyChange(final RunnableEvent event) {
listener.onEvent(event);
}
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;
}
}
}
public class ThreadLifeCycleListener implements LifeCycleListener {
private final Object LOCK = new Object();
public void query(List<String> ids) {
if (ids == null || ids.isEmpty()) {
return ;
}
ids.stream().forEach(id->new Thread(new AbservableRunnable(this) {
@Override
public void run() {
try {
notifyChange(new RunnableEvent(RunnableState.RUNNING, Thread.currentThread(), null));
System.out.println("Query for the id : " + id);
Thread.sleep(1000);
notifyChange(new RunnableEvent(RunnableState.DONE, Thread.currentThread(), null));
} catch (Exception e) {
notifyChange(new RunnableEvent(RunnableState.ERROR, Thread.currentThread(), e));
}
}
}, id).start());
}
@Override
public void onEvent(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();
}
}
}
}
public class ThreadLifeCycleMain {
public static void main(String[] args) {
new ThreadLifeCycleListener().query(Arrays.asList("100", "200"));
}
}
运行结果:
The runnable 【100】, data changed and state is 【RUNNING】
The runnable 【200】, data changed and state is 【RUNNING】
Query for the id : 200
Query for the id : 100
The runnable 【100】, data changed and state is 【DONE】
The runnable 【200】, data changed and state is 【DONE】