kotlin并發(fā)性

kotlin并發(fā)性

新開始讀G. Blake Meike寫的"Android Concurrency",到目前為止我非常推薦這本偉大的書允青,

它包含了許多關(guān)于不同的Android并發(fā)機(jī)制如何工作的深刻見解萌衬,當(dāng)您更喜歡一種實(shí)現(xiàn)方式而不是另一種實(shí)現(xiàn)方式時(shí)姜盈,如何獲得最好的方法径缅。

我決定學(xué)習(xí)書中的例子,并且重寫這些例子姜胖。由于我非常地?zé)釔踜otlin誉帅,我覺得把這些例子用kotlin實(shí)現(xiàn)是個不錯的主意。

在Android Concurrency書的第一章右莱,作者使用java中最基本的并發(fā)語法蚜锨,因此現(xiàn)在我開始使用kotlin書寫這些代碼例子,我非常驚奇的發(fā)現(xiàn):

在kotlin中沒有synchronized 關(guān)鍵字

在kotlin中沒有volatile 關(guān)鍵字

kotlin中的Any和java中的Object相似慢蜓,但是沒有wait(), notify() 和 notifyAll() 三個方法

那么并發(fā)是如何在kotlin中工作的呢亚再?這個問題已經(jīng)在kotlin forum中被問到了。如下是kotlin項(xiàng)目leader Andrey Breslav的回答:

Kotlin故意沒有構(gòu)建語言的并發(fā)性晨抡。我們認(rèn)為這應(yīng)該由libraries來處理氛悬。

盡管kotlin沒有把并發(fā)性內(nèi)置在語音中,但是仍然提供了很多低語言的并發(fā)語法≡胖現(xiàn)在如捅,讓我們來看看這些語法。

Creating Threads

在java中有兩種方法創(chuàng)建一個線程:

1:擴(kuò)展Thread類

2:實(shí)例化Thread類并且通過構(gòu)造函數(shù)傳入一個Runnable

因?yàn)槟隳軌騥otlin中簡單的使用java 類调煎,上述兩種方法也可以很好的起作用镜遣。

下面展示如下子類化Thread:

object : Thread() {
     override fun run() { 
         println("running from Thread:${Thread.currentThread()}")
     }
}.start()

這部分代碼使用到了kotlin的Object 表達(dá)式創(chuàng)建匿名類,并且重寫了run()方法士袄。此處將會演示如何傳入一個Runnable對象來創(chuàng)建Thread的實(shí)例:

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

在這你并沒有看到Runnable對象悲关,在kotlin中你能夠很容易的使用lambda表達(dá)式谎僻。是否還有更好的方法呢?當(dāng)然寓辱!下面將會演示如果使用kotlin風(fēng)格實(shí)例化并且啟動一個線程:

thread(start=true) {
    println("running from thread():${Thread.currentThread()}")
}

很簡潔戈稿,不是么?我們正在使用thread()方法讶舰,它會神奇地隱藏所有的樣板代碼。事實(shí)上需了,下面將展示完成的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
}

它只是一個非常方便的包裝函數(shù)跳昼,使用起來很方便。

Synchronized Methods and Blocks

在kotlin中肋乍,synchronized不是一個關(guān)鍵字鹅颊,使用@Synchronized注解。

在kotlin中一個synchronized方法的聲明看起來如下所示:

@Synchronized fun synchronizedMethod() {
    println("inside a synchronized method:${Thread.currentThread()}")
}

這個注解和Java中的synchronized有同樣的效果:它將把JVM方法標(biāo)記為同步墓造。對應(yīng)同步代碼塊堪伍,你不得不使用synchronized()方法,這將會使用一個lock作為一個參數(shù):

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

代碼的外觀和行為與Java變量非常相似觅闽。

Volatile Fields

同樣地帝雇,在kotlin中沒有volatile關(guān)鍵字,但是有@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支持字段標(biāo)記為volatile。

wait(), notify() and notifyAll()

在kotlin中孕锄,每一個類都是從Any繼承過來的吮廉,但是Any并沒有聲明wait(),notify()和notifyAll()方法,這就意味著畸肆,你不能在kotlin類中調(diào)用這些方法宦芦。但是你仍然能夠使用java.lang.Object的實(shí)例作為lock,并且調(diào)用相關(guān)的方法轴脐。下面將會展示一個使用Objec做為lock解決生產(chǎn)者和消費(fèi)者的問題调卑,

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(譯者注:不是很明白)

事實(shí)是如果在你的代碼中使用如此low-level constructs,看起來正在做一些錯誤的事情了大咱。如今無論是在java中還是kotlin中都有很多高級的并發(fā)機(jī)制滿足每一個需求令野,在Stackoverflow上面有一個非常棒的回答,并且提供了一系列可用的工具來寫并發(fā)代碼徽级。

文章中的代碼已經(jīng)發(fā)布到GitHub气破,請參考。

Conclusion

盡快在項(xiàng)目中不會被頻繁地使用到餐抢,但是了解和理解基礎(chǔ)的知識還是比較重要的现使。最終發(fā)現(xiàn)在kotlin和java還是有一些不同的地方低匙,但是主要的機(jī)制是一樣的。請記住碳锈,kotlin和java的交互時(shí)候非常棒的顽冶,所以如果kotlin 沒有counterparts,你就可以依賴Java類售碳。玩得開心!

原文地址鏈接:https://blog.egorand.me/concurrency-primitives-in-kotlin/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末强重,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贸人,更是在濱河造成了極大的恐慌间景,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艺智,死亡現(xiàn)場離奇詭異倘要,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)十拣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門封拧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人夭问,你說我怎么就攤上這事泽西。” “怎么了缰趋?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵尝苇,是天一觀的道長。 經(jīng)常有香客問我埠胖,道長糠溜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任直撤,我火速辦了婚禮非竿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谋竖。我一直安慰自己红柱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布蓖乘。 她就那樣靜靜地躺著锤悄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嘉抒。 梳的紋絲不亂的頭發(fā)上零聚,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼隶症。 笑死政模,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蚂会。 我是一名探鬼主播淋样,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼胁住!你這毒婦竟也來了趁猴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤彪见,失蹤者是張志新(化名)和其女友劉穎儡司,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體企巢,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年让蕾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浪规。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡探孝,死狀恐怖笋婿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情顿颅,我是刑警寧澤缸濒,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站粱腻,受9級特大地震影響庇配,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绍些,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一捞慌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柬批,春花似錦啸澡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至上沐,卻和暖如春皮服,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工冰更, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留产徊,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓蜀细,卻偏偏與公主長得像舟铜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子奠衔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,072評論 25 707
  • 本文出自 Eddy Wiki 谆刨,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,113評論 0 14
  • 年初的預(yù)想是一天記一篇,堅(jiān)持了四天归斤。不是我軍不努力痊夭,無奈考試周有高達(dá)。 一學(xué)期算下來脏里,誠心正意地她我,把駁雜的心緒放到...
    秋庫里閱讀 389評論 0 0
  • 世界上有很多職業(yè),大多數(shù)是人們非常熟悉的迫横,比如老師番舆,醫(yī)生,律師矾踱,警察恨狈。這些尋常的職業(yè)存在于我們?nèi)粘5纳钪校瑹o人不...
    畫歌Echo閱讀 762評論 4 9
  • 婚姻好的時(shí)候很幸福呛讲,不好的時(shí)候也挺煩人禾怠!不好的時(shí)候就多想想好的時(shí)候吧!于是我寫下我們好的時(shí)候贝搁,等到不好的時(shí)候再翻出...
    奕橙閱讀 575評論 2 6