天天看点

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)