代码语言:javascript复制
import android.os.Handler;
import android.os.HandlerThread;
import androidx.annotation.Nullable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 一个在设计在不同线程中运行,异步通知数据的类
*
* @param <Param> 运行参数类型
* @param <Result> 返回结果类型
*/
public abstract class Promise<Param, Result>
{
// 初始化
private static final int STATUS_INIT = 0;
// 正在请求
private static final int STATUS_REQUESTING = 1;
// 请求结束
private static final int STATUS_FINISH = 2;
// 当前线程
private final AtomicInteger status = new AtomicInteger(0);
// 进行超时返回设计,所使用的线程池
private final static ExecutorService executor = Executors.newCachedThreadPool();
// 专门Promise使用的,子线程
private final static HandlerThread thread = new HandlerThread("Promise-Handler");
// 使用阻塞获取所用到的BlockingQueue
private final LinkedBlockingQueue<Result> queue = new LinkedBlockingQueue<>();
// 代码执行所在的Handler
private Handler handler;
// 所需要的参数
private final Param[] params;
// 默认的超时返回时间
private long time_out = 7_000;
@SafeVarargs
public Promise(Param... params)
{
this(null, params);
}
@SafeVarargs
public Promise(Handler handler, Param... params)
{
this.params = params;
if (handler == null)
{
if (!thread.isAlive())
{
thread.start();
}
this.handler = new Handler(thread.getLooper());
} else
{
this.handler = handler;
}
}
/**
* 设置超时时间
*
* @param time_out 超时时间
*/
public void setTimeOut(long time_out)
{
this.time_out = time_out;
}
/**
* 设置Handler
*
* @param handler 设置run函数运行在哪个Handler里
*/
public void setHandler(Handler handler)
{
this.handler = handler;
}
/**
* 在handler中执行的run函数
*
* @param params run所需要的参数
*/
protected abstract void run(Param... params);
/**
* 发射
*
* @param result 等待那边需要的数据
*/
public void emit(@Nullable Result result)
{
queue.offer(result);
}
/**
* 获取数据,使用默认的超时时间,默认值为 null
*
* @return 获取的数据
*/
public Result get()
{
return this.get(this.time_out, null);
}
/**
* 获取数据,超出超时时间,则获取默认值
*
* @param time_out 超时时间
* @param def 默认值
* @return 获取值
*/
public Result get(long time_out, Result def)
{
if (Thread.currentThread() == handler.getLooper().getThread())
{
throw new RuntimeException("当前线程,和handler所在的线程不能是同一个线程,因为会阻塞当前线程,进行死锁。");
}
if (status.compareAndSet(STATUS_INIT, STATUS_REQUESTING))
{
handler.post(() -> this.run(params));
}
if (status.compareAndSet(STATUS_FINISH, STATUS_FINISH))
{
return def;
}
Callable<Result> callable = queue::take;
FutureTask<Result> futureTask = new FutureTask<>(callable);
executor.submit(futureTask);
try
{
return futureTask.get(time_out, TimeUnit.MILLISECONDS);
} catch (Exception e)
{
return def;
} finally
{
status.set(STATUS_FINISH);
}
}
}