天天看點

Kotlin實戰指南十六:Synchronized、Volatile

文章目錄

  • 如何建立線程 Thread
  • 如何使用 Synchronized 同步鎖
    • 例子1
    • 例子2
  • Volatile 關鍵字
  • 預設指派
    • 預設不為空
    • 可以為空
    • 預設值
    • 兩個預設值
  • 構造函數
  • 重載函數 `@JvmOverloads `

在Kotlin 中,我們仍然可以使用 java 的文法建立一個線程

Thread(Runnable { 
        
}).start()

 //或者使用 Lambda 表達式
Thread {

}.start()  
           

事實上,kotlin 為我們提供了一個簡單寫法:

Kotlin中可以使用thread()方法建立新的線程,指定的語句塊将在新線程中運作。文法簡單,十分易用。

fun main() {
    thread {
        Log.d("yanjun", "開啟一個線程")
    }
}
           

用法夠簡單吧。你會好奇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
}
           

可以看到 start 參數預設為 true ,自動執行線程。當然也可以通過 name 字段指定線程的名字:

fun main() {
   
   //指定線程的名字,是否自動執行
    thread(start = true, name = "my_thread") {

    }
}
           

在Java中,給一個方法加鎖 ,需要給方法加 synchronized 關鍵字

public synchronized void run() {

}
           

kotlin 中沒有 synchronized 關鍵之,取而代之的是 @Synchronized 注解

class Util {

    @Synchronized
    fun main() {

    }
}

           

我們把 kotlin 代碼反編譯一下看看,

Kotlin實戰指南十六:Synchronized、Volatile

可以看到 @Synchronized 注解 可以達到 Java synchronized 關鍵字的作用。

除此之外,kotlin 在方法内,可以使用 block 塊

class Util {

    val lock = Any()

    fun main() {
        synchronized(this) {

        }
    }
}
           

編譯成 java 如下

Kotlin實戰指南十六:Synchronized、Volatile

class Util {

    val lock = Any()

    fun main() {
        synchronized(lock) {

        }
    }
}
           
Kotlin實戰指南十六:Synchronized、Volatile

kotlin

中沒有

volatile

關鍵字,但是有

@Volatile

注解

class Util {

    @Volatile
    var lock = Any()
}
           
Kotlin實戰指南十六:Synchronized、Volatile

class A(val name: String, val age: Int)
           

代表 name、age 不能為 null , 轉換成 java , 會看到在構造函數中會對 name 字段做 空校驗。

Kotlin實戰指南十六:Synchronized、Volatile
Kotlin實戰指南十六:Synchronized、Volatile

class A(val name: String?, val age: Int)
           

代表 name 可為 null , 轉換成 java , 會看到在構造函數中沒有對 name 字段做 空校驗。

Kotlin實戰指南十六:Synchronized、Volatile

class A(val name: String? = "zhaoyanjun", val age: Int)
           

name 可為空,如果name 為null, 使用預設值 “zhaoyanjun”

Kotlin實戰指南十六:Synchronized、Volatile

class A(val name: String? = "zhaoyanjun", val age: Int ?= 10)
           
Kotlin實戰指南十六:Synchronized、Volatile
class A(val name: String, val age: Int)

var a1 =  A("zhaoyanjun",10)  //編譯正常
var a =  A()  //編譯失敗,因為沒有無參構造函數
           
Kotlin實戰指南十六:Synchronized、Volatile

如何才能調用無參構造函數呢?其實很簡單,給每個參數添加一個預設值就可以了

class A(val name: String? = "", val age: Int? = 0)
           

隻要參數都有預設值,就會預設生成 無參構造函數

Kotlin實戰指南十六:Synchronized、Volatile

重載函數

@JvmOverloads

class A(val name: String, val age: Int)

var a1 =  A("zhaoyanjun",10)   //編譯正常
var a2 =  A("123")    //編譯失敗,沒有隻有一個參數的構造函數
           
  • 給每個參數添加預設值
  • 标記

    constructor

    關鍵字
  • @JvmOverloads

class A @JvmOverloads constructor(val name: String? = "", val age: Int? = 0)