Android中使用Java简单模拟kotlin中的协程

这篇博客对比了 Kotlin 协程和 Java 中的线程切换实现,展示了如何在 Java 中用注解和 Handler 模拟协程的线程切换,并探讨了 Kotlin 协程内部的线程池机制。通过示例代码,我们可以看到 Kotlin 的 lambda 表达式简化了代码,但核心原理相似。文章还简要分析了 Kotlin 协程调度器的实现,揭示了其与线程池的联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kotlin协程切换线程在编码过程中非常简单高效,在Java中简单模拟一下

首先定义一个注解,用来作为线程切换的标记

@Retention(RetentionPolicy.SOURCE)
@IntDef({Dispatcher.IO, Dispatcher.Main})
public @interface Dispatcher {
    int IO = 0;
    int Main = 1;
}

接着构建一个"协程"类:其中主要由线程池以及Handler构成

public class Coroutine {
    private static final Handler mHandler = new Handler(Looper.getMainLooper());
    private static final ThreadPoolExecutor es = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
    public static void withContext(@com.enjoy.okhttp.coroutine.Dispatcher int type, Runnable runnable) {
        if (runnable == null) {
            throw new RuntimeException("no runnable can be executed");
        }
        if (type == Dispatcher.IO) {
            es.execute(runnable);
        } else if (type == Dispatcher.Main) {
            mHandler.post(runnable);
        }
    }
}

再看看使用:

 //将任务切换到IO线程中执行
        withContext(Dispatcher.IO, () -> {
            try {
                Response response = call.execute();
                ResponseBody responseBody = response.body();
                //切换到主线程更新UI
                withContext(Dispatcher.Main, () -> {
                    try {
                        assert responseBody != null;
                        byte[] bitMapBytes = responseBody.bytes();
                        Bitmap bitmap = BitmapFactory.decodeByteArray(bitMapBytes, 0, bitMapBytes.length);
                        imageView.setImageBitmap(bitmap);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

然后看看效果

让我们再来看一下kotlin中的协程写法

 //换到子线程执行耗时任务
        withContext(Dispatchers.IO) {
            val response = call.execute()
            val responseBody = response.body()
            //主线程更新UI
            withContext(Dispatchers.Main) {
                val bitMapBytes = responseBody?.bytes()
                val bitMap = BitmapFactory.decodeByteArray(bitMapBytes, 0, bitMapBytes?.size!!)
                iv_show?.setImageBitmap(bitMap)
            }
        }

 可以看出来,除了kotlin的lambda可以简写以外,其他方面区别不大。

然后简单深入看一下kt 的协程,点开 Dispatchers,

override val executor: Executor
        get() = coroutineScheduler、

 private fun createScheduler() = CoroutineScheduler(corePoolSize, maxPoolSize, idleWorkerKeepAliveNs, schedulerName)、

internal class CoroutineScheduler(
    @JvmField val corePoolSize: Int,
    @JvmField val maxPoolSize: Int,
    @JvmField val idleWorkerKeepAliveNs: Long = IDLE_WORKER_KEEP_ALIVE_NS,
    @JvmField val schedulerName: String = DEFAULT_SCHEDULER_NAME
) : Executor, Closeable {
    init {
        require(corePoolSize >= MIN_SUPPORTED_POOL_SIZE) {
            "Core pool size $corePoolSize should be at least $MIN_SUPPORTED_POOL_SIZE"
        }
        require(maxPoolSize >= corePoolSize) {
            "Max pool size $maxPoolSize should be greater than or equals to core pool size $corePoolSize"
        }
        require(maxPoolSize <= MAX_SUPPORTED_POOL_SIZE) {
            "Max pool size $maxPoolSize should not exceed maximal supported number of threads $MAX_SUPPORTED_POOL_SIZE"
        }
        require(idleWorkerKeepAliveNs > 0) {
            "Idle worker keep alive time $idleWorkerKeepAliveNs must be positive"
        }
    }
...

有没有很眼熟,对了就是线程池。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值