cn.keayuan.util.flow.FlowProcess Maven / Gradle / Ivy
package cn.keayuan.util.flow;
import java.io.Closeable;
import java.util.concurrent.Executor;
import java.util.concurrent.locks.ReentrantLock;
import cn.keayuan.util.ObjectUtils;
import cn.keayuan.util.Platform;
import cn.keayuan.util.ThreadUtils;
/**
* Created by keayuan on 2021/1/29.
*
* @author keayuan
*/
public class FlowProcess implements IFlow
{
private static Executor ioExecutor;
private static Executor mainExecutor;
private Node, ?> head;
private Node, ?> tail;
volatile boolean isClose;
private volatile boolean isStart;
private final ReentrantLock mLock = new ReentrantLock();
static {
setMainExecutor(Platform.getMainExecutor());
setIOExecutor(ThreadUtils.getIOPool());
}
public static IFlow create(T t) {
return new FlowProcess<>(t);
}
public static void setMainExecutor(Executor executor) {
FlowProcess.mainExecutor = executor;
}
public static void setIOExecutor(Executor executor) {
FlowProcess.ioExecutor = executor;
}
private static void execute(Node, ?> node) {
if (node == null) {
return;
}
(node.isMain() ? mainExecutor : ioExecutor).execute(node);
}
private FlowProcess(P first) {
tail = head = new Node<>(first, this);
}
@SuppressWarnings("unchecked")
private IFlow add(String tag, IProcess p, boolean main) {
if (isStart) {
throw new IllegalStateException("process already start, don't add Process.");
}
if (p != null) {
mLock.lock();
tail.next = new Node(tag, p, main, this);
tail = tail.next;
mLock.unlock();
}
return (IFlow) this;
}
@Override
public IFlow main(IProcess p) {
return main(null, p);
}
@Override
public IFlow main(String tag, IProcess p) {
return add(tag, p, true);
}
@Override
public IFlow io(IProcess p) {
return io(null, p);
}
@Override
public IFlow io(String tag, IProcess p) {
return add(tag, p, false);
}
@Override
public void remove(String tag) {
mLock.lock();
while (head != null && ObjectUtils.equals(tag, head.getTag())) head = head.next;
if (head != null) {
Node, ?> pre = head;
Node curr = pre.next;
while (curr != null) {
if (ObjectUtils.equals(tag, curr.getTag())) {
pre.next = curr.next;
curr = pre;
}
curr = curr.next;
}
}
mLock.unlock();
}
@Override
public Closeable start() {
isStart = true;
mLock.lock();
Object temp = head.getParams();
head = head.next;
next(null, temp);
mLock.unlock();
return this;
}
void next(String tag, Object arg) {
if (isClose) {
throw new IllegalStateException("process already close");
}
mLock.lock();
if (head == null) {
throw new IllegalStateException("node already end");
}
Node curr = head;
if (tag != null) {
while (curr != null && !ObjectUtils.equals(tag, curr.getTag())) curr = curr.next;
if (curr == null) {
throw new IllegalStateException("tag not exist " + tag);
}
}
head = curr.next;
curr.setParams(arg);
FlowProcess.execute(curr);
mLock.unlock();
}
@Override
public void close() {
isClose = true;
mLock.lock();
head = null;
mLock.unlock();
}
}