Kotlin中的并发原语
来源:互联网 发布:建行软件下载 编辑:程序博客网 时间:2024/06/05 18:30
本文译自:https://blog.egorand.me/concurrency-primitives-in-kotlin/
我最近在阅读G. Blake Meike的“Android Concurrency一书”,到目前为止,我强烈推荐这本非常棒的书:它包含了很多洞察各种Android并发机制是如何的工作,何时使用这种方式而不是另一种方式,以及如何更好的使用各种工具。我决定遵循代码示例,在我的电脑上重新创建它们,并且由于我非常喜爱Kotlin,我认为将这些示例不断地转换为Kotlin是一个不错的注意。在第一章中作者回顾了Java中的并发基础知识,当我开始重写Kotlin中的代码示例时,我非常惊讶地发现:
- Kotlin中没有synchronized关键字
- Kotlin中没有volatile关键字
- Kotlin的Any类似于Java的Object,没有wait(),notify()和notifyAll()方法
那么并发如何在Kotlin中工作呢?这个问题已经在Kotlin论坛上提出,这里是来自Andrey Breslav,Kotlin项目负责人的回答:
Kotlin故意没有内置并发语言的构造。我们认为这应该由第三方libraries处理。
虽然Kotlin没有内置的这些东西,它仍然提供了一堆低级并发工具。让我们来看看都有什么。
创建线程
在Java中有两种方法创建线程:扩展Thread类,或者实例化它并通过构造函数传递一个Runnable。 因为你可以很容易地在Kotlin中使用Java类,这两个解决方案都很好。 下面是如何创建子类Thread:
object : Thread() { override fun run() { println("running from Thread: ${Thread.currentThread()}") }}.start()
这段代码使用Kotlin的对象表达式来创建一个匿名类并覆写run方法,下面是如何给新创建的Thread实例传递一个Runnable。
Thread({ println("running from lambda: ${Thread.currentThread()}")}).start()
这里Runnable是不可见的:在Kotlin中,它可以很容易地替换为lambda表达式。 有更好的方法吗? 当然! 以下是如何以Kotlin风格实例化和启动线程:
thread(start = true) { println("running from thread(): ${Thread.currentThread()}")}
整洁,不是吗? 我们正在使用thread()函数,它神奇地隐藏所有的样板代码。 事实上,thread()中没有魔法:
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中synchronized不是一个关键字,它被@Synchronized注解所代替。在Kotlin中同步方法的声明如下:
@Synchronized fun synchronizedMethod() { println("inside a synchronized method: ${Thread.currentThread()}")}
这个注解和Java中的synchronized是同样的效果。它会将JVM方法标记为同步。对于同步代码块你应该使用synchronized()
方法,它使用锁作为参数:
fun methodWithSynchronizedBlock() { println("outside of a synchronized block: ${Thread.currentThread()}") synchronized(this) { println("inside a synchronized block: ${Thread.currentThread()}") }}
此代码的样子和行为非常类似于Java变体。
Volatile
同样的,Kotlin没有volatile关键字,但是有@Volatileannotation注解:
@Volatile private var running = falsefun start() { running = true thread(start = true) { while (running) { println("Still running: ${Thread.currentThread()}") } }}fun stop() { running = false println("Stopped: ${Thread.currentThread()}")}
该行为类似于@Synchronized:@Volatile会将JVM备份字段标记为volatile。
wait(), notify() and notifyAll()
Kotlin中的每个类都继承自Any,但Any类中没有声明wait(),notify()和notifyAll(),这意味着这些方法不能在Kotlin类上调用。 但是你仍然可以使用java.lang.Object的一个实例作为锁,并调用它的方法。 这里是使用Object作为锁的生产者/消费者问题的解决方案:
private val lock = java.lang.Object()fun produce() = synchronized(lock) { while (items >= maxItems) { lock.wait() } Thread.sleep(rand.nextInt(100).toLong()) items++ println("Produced, count is $items: ${Thread.currentThread()}") lock.notifyAll()}fun consume() = synchronized(lock) { while (items <= 0) { lock.wait() } Thread.sleep(rand.nextInt(100).toLong()) items-- println("Consumed, count is $items: ${Thread.currentThread()}") lock.notifyAll()}
它看起来很容易吗? 好吧,是的。 真理是,如果你在代码中依赖这样的低级结构 - 很可能你做错了。 现在有很多高级并发机制用于Java和Kotlin的每一个目的。 Stackoverflow上有一个非常好的的答案,提供了可用于在Kotlin中编写并发代码的工具列表。
本文的所有代码示例都可以在GitHub上获取。
总结
虽然它们不常使用,但了解和了解基本的并发工具仍然很重要。 事实这在Kotlin和Java中的工作机制有些不同,但所有主要机制都支持。记住Kotlin的与Java的交互性非常好,因此当Koltlin中某些类缺失了,你完全可以依赖Java中对等的类。 玩的开心!
- Kotlin中的并发原语
- Kotlin中的并发原语
- java并发中的原子类
- 计算机网络中的服务原语
- unix中的PV原语
- 计算机网络中的服务原语
- Java 并发:原子类
- 并发操作: Windows Vista 新增的同步原语
- memcached(十八)并发原语CAS与GETS操作
- memcached 并发原语CAS与GETS操作
- memcached(十八)并发原语CAS与GETS操作
- memcached 并发原语CAS与GETS操作
- eCos中的同步原语简要
- eCos中的同步原语简要
- 并发编程--原子类AotmicInteger
- 线程并发学习----原子类
- Android 开发中的KotLin
- Kotlin中的关键字(1)
- python3操作mysql数据库
- 小朋友学C++(5):构造函数
- 小朋友学C++(6):this指针
- 面向对象:愿有一人,令我喜你成疾,药石无医
- 趣图:在 2G 内存电脑上运行 Android Studio
- Kotlin中的并发原语
- JAVA二叉树
- 小朋友学C++(7):封装
- 对全连接层的深入理解
- 为什么我讨厌开放式办公?
- python中遍历list的三种方式
- 小朋友学C++(8):继承
- BZOJ 5085(最大-经典题)
- Android数据库操作—— GreenDao让你的数据操作更简单