文章19 | 阅读 9952 | 点赞0
1.协程:Coroutine
2.如何去理解协程: 可以视为轻量级的线程
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
我们可以看到start0是一个native方法,也就是说开启一个线程实际上是需要jvm同底层操作系统进行打交道的。那么我们可以用一句话总结就是:线程是系统级别的,它的开销是巨大的,比较耗费计算机资源,而协程是轻量级的,开销小。
3.编写第一个协程代码:
fun main() {
GlobalScope.launch {
delay(1000)
println("world")
}
println("hello")
Thread.sleep(2000)
println("welcome")
}
输出结果:
hello
(等待1s)
world
(等待1s)
welcome
这段代码我们待会儿再来解释,我们再来看一个熟悉的例子:
fun main() {
Thread{
Thread.sleep(1000)
println("world")
}.start()
println("hello")
Thread.sleep(2000)
println("welcome")
}
输出结果同上面一样,等待时间也是一样的。后面这段代码易懂,我们按照时间顺序来解释:
理解到这,我们再来对比第一段协程代码:
同样,我们按照时间顺序来解释协程代码:
现在,我们针对第一段协程代码,稍微改动一下主线程的休眠时间,将2000毫秒改为500毫秒,再来看一看运行结果:
hello
休眠0.5s
welcome
好了,到这程序就运行结束了,"world"永远也不会有机会输出。为什么呢?
程序都已经退出了,那么协程当然也就不存在了。感兴趣你还可以针对第二段线程代码进行同样的修改,看看结果有什么不同,这里就不再详述了。
4.GlobalScope.launch{}
Launches a new coroutine without blocking the current thread and returns a reference to the coroutine as a [Job]
这是launch方法的描述,翻译过来就是:它会在不阻塞当前线程的前提下去启动一个新的协程,然后返回一个关联该协程的Job类型的引用。
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
val newContext = newCoroutineContext(context)
val coroutine = if (start.isLazy)
LazyStandaloneCoroutine(newContext, block) else
StandaloneCoroutine(newContext, active = true)
coroutine.start(start, coroutine, block)
return coroutine
}
另外从源代码的角度上可以看出:launch是CoroutineScope的一个扩展方法,并且返回值是一个Job类型
/**
* Defines a scope for new coroutines. Every coroutine builder
* is an extension on [CoroutineScope] and inherits its [coroutineContext][CoroutineScope.coroutineContext]
* to automatically propagate both context elements and cancellation.
*/
public interface CoroutineScope {
/**
* The context of this scope.
* Context is encapsulated by the scope and used for implementation of coroutine builders that are extensions on the scope.
* Accessing this property in general code is not recommended for any purposes except accessing [Job] instance for advanced usages.
*
* By convention, should contain an instance of a [job][Job] to enforce structured concurrency.
*/
public val coroutineContext: CoroutineContext
}
用来定义协程的作用范围,有个概念就行。
public object GlobalScope : CoroutineScope {
/**
* Returns [EmptyCoroutineContext].
*/
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
}
可以看出,GlobalScope是一个实现了CoroutineScope接口的对象,并且重写coroutineContext的get方法。
当然,CoroutineScope.launch{}只是启动协程的方式之一,Kotlin还提供了其他启动协程的方式,这些方式或者叫方法有一个名字,叫做协程建造器(coroutine builder)。我们将在接下来的篇章去进行介绍
5.补充:
我们刚刚在创建一个线程时,使用了如下代码:
Thread{
....
}.start()
实际上Kotlin中提供一种更为简便的方式:
thread {
...
}
这个thread实际上一个顶级函数(top-level function),在kotlin.concurrent包下,它的实现如下:
public fun thread(
start: Boolean = true,
isDaemon: Boolean = false,
contextClassLoader: ClassLoader? = null,
name: String? = null,
priority: Int = -1,
block: () -> Unit
): Thread {
val thread = object : Thread() {
public override fun run() {
block()
}
}
if (isDaemon)
thread.isDaemon = true
if (priority > 0)
thread.priority = priority
if (name != null)
thread.name = name
if (contextClassLoader != null)
thread.contextClassLoader = contextClassLoader
if (start)
thread.start()
return thread
}
实现也是一看就懂,就是Kotlin为了开发者编码方便而做了一层封装。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/xlh1191860939/article/details/96647530
内容来源于网络,如有侵权,请联系作者删除!