Channel 通道 其 本质是一个 先进先出 队列 ;
Channel 通道 中维护了一个 缓冲区 , 该缓冲区有一定的 容量 ;
调用 Channel#send 函数 , 会 向缓冲区中发送数据 ,
调用 Channel#receive 函数 , 会从缓冲区中抽取数据 ,
如果 缓冲区 数据满了 , 则 Channel#send 函数就会挂起 ,
直到 调用 Channel#receive 函数 取走了缓冲区中的数据 , 缓冲区 有了空间 , Channel#send 函数才会恢复执行 ;
代码示例 : 产生数据的频率是 1 秒一个 , 消费数据的频率是 2 秒一个 , 那么需要等待数据消费后 也就是 2 秒 才能消费一个数据 , 产生数据后 1 秒是处于挂起状态的 ;
package kim.hsl.coroutine
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
runBlocking {
// Channel 通道, 传递 Int 类型数据
val channel = Channel<Int>()
// 数据生产者协程
val producer = GlobalScope.launch {
for (i in 0..3) {
delay(1000)
channel.send(i)
println("向通道中发送数据 $i")
}
}
// 数据消费者协程
val consumer = GlobalScope.launch {
while (true) {
delay(2000)
val num = channel.receive()
println("从通道中获取数据 $num")
}
}
}
}
}
}
执行结果 :
21:35:47.097 System.out kim.hsl.coroutine I 从通道中获取数据 0
21:35:47.098 System.out kim.hsl.coroutine I 向通道中发送数据 0
21:35:49.137 System.out kim.hsl.coroutine I 从通道中获取数据 1
21:35:49.137 System.out kim.hsl.coroutine I 向通道中发送数据 1
21:35:51.177 System.out kim.hsl.coroutine I 从通道中获取数据 2
21:35:51.178 System.out kim.hsl.coroutine I 向通道中发送数据 2
21:35:53.218 System.out kim.hsl.coroutine I 从通道中获取数据 3
21:35:53.219 System.out kim.hsl.coroutine I 向通道中发送数据 3
Channel 通道 其 本质是一个 先进先出 队列 ;
可以使用 Channel#iterator 对 Channel 通道 进行 迭代 ;
首先 , 调用 channel.iterator()
获取迭代器 ;
然后 , 调用 iterator.hasNext()
检查是否有下一个元素 ,
最后 , 调用 iterator.next()
获取下一个元素 ;
核心代码如下 :
val iterator = channel.iterator()
while (iterator.hasNext()) {
delay(1000)
val num = iterator.next()
println("从通道中获取数据 $num")
}
完整代码示例 :
package kim.hsl.coroutine
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
runBlocking {
// Channel 通道, 缓冲区大小无限大
val channel = Channel<Int>(Channel.UNLIMITED)
// 数据生产者协程
val producer = GlobalScope.launch {
for (i in 0..3) {
channel.send(i)
println("向通道中发送数据 $i")
}
}
// 数据消费者协程
val consumer = GlobalScope.launch {
while (true) {
val iterator = channel.iterator()
while (iterator.hasNext()) {
delay(1000)
val num = iterator.next()
println("从通道中获取数据 $num")
}
}
}
}
}
}
}
执行结果 :
21:48:02.741 System.out kim.hsl.coroutine I 向通道中发送数据 0
21:48:02.741 System.out kim.hsl.coroutine I 向通道中发送数据 1
21:48:02.742 System.out kim.hsl.coroutine I 向通道中发送数据 2
21:48:02.743 System.out kim.hsl.coroutine I 向通道中发送数据 3
21:48:02.778 OpenG...erer kim.hsl.coroutine D Skia GL Pipeline
21:48:03.770 System.out kim.hsl.coroutine I 从通道中获取数据 0
21:48:04.808 System.out kim.hsl.coroutine I 从通道中获取数据 1
21:48:05.847 System.out kim.hsl.coroutine I 从通道中获取数据 2
21:48:06.887 System.out kim.hsl.coroutine I 从通道中获取数据 3
使用 for in 循环 对 Channel 通道进行迭代 , 核心代码如下 :
for(num in channel) {
delay(1000)
println("从通道中获取数据 $num")
}
代码示例 :
package kim.hsl.coroutine
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
runBlocking {
// Channel 通道, 缓冲区大小无限大
val channel = Channel<Int>(Channel.UNLIMITED)
// 数据生产者协程
val producer = GlobalScope.launch {
for (i in 0..3) {
channel.send(i)
println("向通道中发送数据 $i")
}
}
// 数据消费者协程
val consumer = GlobalScope.launch {
while (true) {
for(num in channel) {
delay(1000)
println("从通道中获取数据 $num")
}
}
}
}
}
}
}
执行结果 :
21:48:02.741 System.out kim.hsl.coroutine I 向通道中发送数据 0
21:48:02.741 System.out kim.hsl.coroutine I 向通道中发送数据 1
21:48:02.742 System.out kim.hsl.coroutine I 向通道中发送数据 2
21:48:02.743 System.out kim.hsl.coroutine I 向通道中发送数据 3
21:48:02.778 OpenG...erer kim.hsl.coroutine D Skia GL Pipeline
21:48:03.770 System.out kim.hsl.coroutine I 从通道中获取数据 0
21:48:04.808 System.out kim.hsl.coroutine I 从通道中获取数据 1
21:48:05.847 System.out kim.hsl.coroutine I 从通道中获取数据 2
21:48:06.887 System.out kim.hsl.coroutine I 从通道中获取数据 3