Promise for Java

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;

/**
 * 一個在設(shè)計在不同線程中運(yùn)行,異步通知數(shù)據(jù)的類
 *
 * @param <Param>  運(yùn)行參數(shù)類型
 * @param <Result> 返回結(jié)果類型
 */
public abstract class Promise<Param, Result>
{
    // 初始化
    private static final int STATUS_INIT = 0;
    // 正在請求
    private static final int STATUS_REQUESTING = 1;
    // 請求結(jié)束
    private static final int STATUS_FINISH = 2;
    // 當(dāng)前線程
    private final AtomicInteger status = new AtomicInteger(0);
    // 進(jìn)行超時返回設(shè)計,所使用的線程池
    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<>();
    // 代碼執(zhí)行所在的Handler
    private Handler handler;
    // 所需要的參數(shù)
    private final Param[] params;
    // 默認(rèn)的超時返回時間
    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;
        }
    }

    /**
     * 設(shè)置超時時間
     *
     * @param time_out 超時時間
     */
    public void setTimeOut(long time_out)
    {
        this.time_out = time_out;
    }

    /**
     * 設(shè)置Handler
     *
     * @param handler 設(shè)置run函數(shù)運(yùn)行在哪個Handler里
     */
    public void setHandler(Handler handler)
    {
        this.handler = handler;
    }

    /**
     * 在handler中執(zhí)行的run函數(shù)
     *
     * @param params run所需要的參數(shù)
     */
    protected abstract void run(Param... params);

    /**
     * 發(fā)射
     *
     * @param result 等待那邊需要的數(shù)據(jù)
     */
    public void emit(@Nullable Result result)
    {
        queue.offer(result);
    }

    /**
     * 獲取數(shù)據(jù),使用默認(rèn)的超時時間,默認(rèn)值為 null
     *
     * @return 獲取的數(shù)據(jù)
     */
    public Result get()
    {
        return this.get(this.time_out, null);
    }

    /**
     * 獲取數(shù)據(jù),超出超時時間,則獲取默認(rèn)值
     *
     * @param time_out 超時時間
     * @param def      默認(rèn)值
     * @return 獲取值
     */
    public Result get(long time_out, Result def)
    {
        if (Thread.currentThread() == handler.getLooper().getThread())
        {
            throw new RuntimeException("當(dāng)前線程,和handler所在的線程不能是同一個線程,因?yàn)闀枞?dāng)前線程,進(jìn)行死鎖。");
        }
        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);
        }
    }
}

感興趣的+> 709287944加Q群交流

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容