Kotlin进行异步操作
?
我(原作者)最近開始閱讀G. Blake Meike的“Android Concurrency”,到目前為止,我可以強烈推薦這本偉大的書:它包含了很多洞察如何各種Android并發機制的工作,何時喜歡一種方法,以及如何獲得最好的工具,在您的處置。我決定遵循代碼示例,并在我的電腦上重新創建它們,并且由于我非常愛Kotlin,我認為這將是一個好主意,將示例轉換為Kotlin在旅途中。當我開始重寫Kotlin中的代碼示例時,我非常驚訝地發現:
Kotlin中沒有synchronized關鍵字
Kotlin中沒有volatile關鍵字
Kotlin的Any類似于Java的Object,沒有wait(),notify()和notifyAll()方法
那么并發如何在Kotlin中工作呢?這個問題已經在Kotlin論壇上提出,這里是來自Andrey Breslav,Kotlin項目負責人的回答:
Kotlin故意沒有內置并發語言的構造。我們認為這應該由圖書館來處理。
雖然Kotlin沒有這些東西內置的語言,它仍然提供了一堆低級并發工具。讓我們來看看商店里有什么。
?
創建線程
有兩種方法在Java中創建線程:擴展Thread類,或者實例化它并通過構造函數傳遞一個Runnable。 因為你可以很容易地在Kotlin中使用Java類,這兩個解決方案都很好。 這里是你如何子類Thread:
object : Thread() { override fun run() {println("running from Thread: ${Thread.currentThread()}")} }.start()此代碼使用Kotlin的對象表達式創建一個匿名類并覆蓋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 = trueif (priority > 0)thread.priority = priorityif (name != null)thread.name = nameif (contextClassLoader != null)thread.contextClassLoader = contextClassLoaderif (start)thread.start()return thread這只是一個非常方便的包裝函數,是一個快樂使用。
同步方法和塊
synchronized不是Kotlin中的關鍵字,它替換為@Synchronizedannotation。 Kotlin中的同步方法的聲明將如下所示:
ps:我是不太明白Kotlin開發團隊的用意,把原來Java中的注解@Override變成了override關鍵字;又把synchronized關鍵字變成了注解@Synchronizedannotation;我只想說? what are you 弄啥嘞!?!
@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變體。
可變字段
同樣的故事,Kotlin沒有volatile關鍵字,但是有@Volatileannotation:
@Volatile private var running = falsefun start() { running = truethread(start = true) {while (running) {println("Still running: ${Thread.currentThread()}")}} }fun stop() { running = falseprintln("Stopped: ${Thread.currentThread()}") }該行為類似于@Synchronized:@Volatile會將JVM備份字段標記為volatile。
wait(), notify() 和 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非常好地交互,所以如果Kotlin對應的方法丟失,你可以依靠Java類。 玩的開心!
原文鏈接:https://blog.csdn.net/sergeycao/article/details/53894787?
原文是譯文,我就直接轉過來了,有的詞用的不像是正常的用語,可能部分是機器翻譯的,能看懂就行了,懶得改了
總結
以上是生活随笔為你收集整理的Kotlin进行异步操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从0开始配置Flutter并运行demo
- 下一篇: Android的Application的