kotlin 子线程睡3秒_kotlin并发性

kotlin并发性

新开始读G. Blake Meike写的"Android Concurrency",到目前为止我非常推荐这本伟大的书,

它包含了许多关于不同的Android并发机制如何工作的深刻见解,当您更喜欢一种实现方式而不是另一种实现方式时,如何获得最好的方法。

我决定学习书中的例子,并且重写这些例子。由于我非常地热爱kotlin,我觉得把这些例子用kotlin实现是个不错的主意。

在Android Concurrency书的第一章,作者使用java中最基本的并发语法,因此现在我开始使用kotlin书写这些代码例子,我非常惊奇的发现:

在kotlin中没有synchronized关键字

在kotlin中没有volatile关键字

kotlin中的Any和java中的Object相似,但是没有wait(), notify() 和 notifyAll() 三个方法

那么并发是如何在kotlin中工作的呢?这个问题已经在kotlin forum中被问到了。如下是kotlin项目leader Andrey Breslav的回答:

Kotlin故意没有构建语言的并发性。我们认为这应该由libraries来处理。

尽管kotlin没有把并发性内置在语音中,但是仍然提供了很多低语言的并发语法。现在,让我们来看看这些语法。

Creating Threads

在java中有两种方法创建一个线程:

1:扩展Thread类

2:实例化Thread类并且通过构造函数传入一个Runnable

因为你能够kotlin中简单的使用java 类,上述两种方法也可以很好的起作用。

下面展示如下子类化Thread:object : Thread() {

override fun run() {

println("running from Thread:${Thread.currentThread()}")

}

}.start()

这部分代码使用到了kotlin的Object 表达式创建匿名类,并且重写了run()方法。此处将会演示如何传入一个Runnable对象来创建Thread的实例: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

}

它只是一个非常方便的包装函数,使用起来很方便。

Synchronized Methods and Blocks

在kotlin中,synchronized不是一个关键字,使用@Synchronized注解。

在kotlin中一个synchronized方法的声明看起来如下所示:@Synchronized fun synchronizedMethod() {

println("inside a synchronized method:${Thread.currentThread()}")

}

这个注解和Java中的synchronized有同样的效果:它将把JVM方法标记为同步。对应同步代码块,你不得不使用synchronized()方法,这将会使用一个lock作为一个参数:fun methodWithSynchronizedBlock() {

println("outside of a synchronized block:${Thread.currentThread()}")

synchronized(this) {

println("inside a synchronized block:${Thread.currentThread()}")

}

}

代码的外观和行为与Java变量非常相似。

Volatile Fields

同样地,在kotlin中没有volatile关键字,但是有@Volatile注解,@Volatile private var running = false

fun 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的实例作为lock,并且调用相关的方法。下面将会展示一个使用Objec做为lock解决生产者和消费者的问题,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()

}

Does it look hacky? Well, it is(译者注:不是很明白)

事实是如果在你的代码中使用如此low-level constructs,看起来正在做一些错误的事情了。如今无论是在java中还是kotlin中都有很多高级的并发机制满足每一个需求,在Stackoverflow上面有一个非常棒的回答,并且提供了一系列可用的工具来写并发代码。

文章中的代码已经发布到GitHub,请参考。

Conclusion

尽快在项目中不会被频繁地使用到,但是了解和理解基础的知识还是比较重要的。最终发现在kotlin和java还是有一些不同的地方,但是主要的机制是一样的。请记住,kotlin和java的交互时候非常棒的,所以如果kotlin 没有counterparts,你就可以依赖Java类。玩得开心!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值