Java程序员对于线程我想都不会陌生,协程在java语言还未被支持。协程是一个比线程更加轻量级的存在,一个线程可以拥有多个协程。轻量级大家可能会有疑惑多轻量级?比如我们普通pc机上,
启动一个进程,然后启动3000个线程,然后你会发现oom了,更不用说通过这些线程处理业务,CPU的轮询就相当耗费时间。有没一种更加轻量级的解决方案呢?那就是协程,我们在一个线程下可以轻松
的开始5000个协程,并不会消耗太多的资源。
举个例子:有这样一个需求,我们需要处理一个网络业务,每个网络业务需要耗时2秒,如何能够快速的处理10w个这个请求,服务器的资源消耗最小,我想大家第一方案就会想到线程池去处理,比如初
始化500个线程到线程池,并发处理这个10w请求,我们大概可以计算出需要耗时400s的时间。如果我们用协程去处理大概花费时间是1s。
给出kotlin代码示例,比较通过协程和线程的耗时情况:
fun main(args: Array<String>) {
println("start coroutine:" + Date())
var count = 100000;
var latch = CountDownLatch(count)
var local = ThreadLocal<String>()
for (i in 1..count) {
CoroutineScope(Dispatchers.Default).launch {
delay(1000)
//执行耗时业务处理
latch.countDown()
}.asCompletableFuture()
}
latch.await()
println("end coroutine:" + Date())
var latch2 = CountDownLatch(count)
println("start thread:" + Date())
for (i in 1..count) {
Thread {
Thread.sleep(1000)
latch2.countDown()
//执行耗时业务处理
}.start()
}
latch2.await()
println("end thread:" + Date())
}
控制台输出:
start coroutine:Sun Jan 31 14:52:52 CST 2021
end coroutine:Sun Jan 31 14:52:53 CST 2021
start thread:Sun Jan 31 14:52:53 CST 2021
end thread:Sun Jan 31 14:53:30 CST 2021
我们从输出的结果可看出,协程只耗费1s完成所有的请求,而通过线程的方式去处理消耗了37s的时间,整整相差37倍的速度,这绝对是一个差距非常的大的一个数据。想想如果我们通过协程去实现一个API网关
是不是可以实现高性能的实现,这一定是一个非常好的实现解决方案。当然协程的作用不单纯只有我说的这些好处。
进程/线程上下文切换会用掉你多少CPU?
https://zhuanlan.zhihu.com/p/79772089
协程究竟比线程能省多少开销?
https://zhuanlan.zhihu.com/p/80037638
当前只说了协程的一个使用场景,更多的使用场景后续在补充上来。协程是一个非常值得学习的概念,他应该是多任务编程的一个未来,也期待Java语音的原生实现。