对kotlin和java中的synchronized的浅谈

Stranger 2019-12-10

synchronized在java中是一个关键字,但是在kotlin中是一个内联函数。假如分别在java和kotlin代码锁住同一个对象,会发生什么呢,今天写了代码试了试。
首先定义people类

12345678910111213
public class  {    public void () {        for (int i = 0; i < 10; i ++) {            try {                Thread.sleep(50);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(String.format("在%s线程中吃第%d个包子", Thread.currentThread().getName(), i));        }    }}

然后定义一个java类开启一个线程并且锁住people

12345678910111213141516171819
public class MyJavaClass {    private final People people;    public MyJavaClass(People people) {        this.people = people;    }    void startThread() {        new Thread(new Runnable() {                        public void run() {                synchronized (people) {                    people.doSomething();                }            }        }, "java").start();    }}

再定义一个kotlin类开启一个线程并且锁住相同的people

12345678910
class MyKotlinClass(private val people: People) {    fun startThread() {        Thread(Runnable {            synchronized(people) {                people.doSomething()            }        }, 大专栏  对kotlin和java中的synchronized的浅谈g">"kotlin").start()    }}

最后在main函数中执行如下代码

123456
fun main(args: Array<String>) {    val people = People()    MyJavaClass(people).startThread()    MyKotlinClass(people).startThread()}

观察输出结果是:

1234567891011121314151617181920
在java线程中吃第0个包子在java线程中吃第1个包子在java线程中吃第2个包子在java线程中吃第3个包子在java线程中吃第4个包子在java线程中吃第5个包子在java线程中吃第6个包子在java线程中吃第7个包子在java线程中吃第8个包子在java线程中吃第9个包子在kotlin线程中吃第0个包子在kotlin线程中吃第1个包子在kotlin线程中吃第2个包子在kotlin线程中吃第3个包子在kotlin线程中吃第4个包子在kotlin线程中吃第5个包子在kotlin线程中吃第6个包子在kotlin线程中吃第7个包子在kotlin线程中吃第8个包子在kotlin线程中吃第9个包子

根据结果可以看到java和kotlin在锁住一个对象时可以做到互斥。但是java中的synchronized是个关键字,kotlin中synchronized是个函数,那么它们为什么做到互斥的呢?
java中synchronized的底层实现这这篇文章中描述的比较清楚https://blog.csdn.net/hbtj_1216/article/details/77773292,关键字synchronized被编译成了monitorenter和monitorexit。再看kotlin中的synchronized函数

123456789101112
.internal.InlineOnlypublic inline fun <R> synchronized(lock: Any, block: () -> R): R {    @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE", "INVISIBLE_MEMBER")    monitorEnter(lock)    try {        return block()    }    finally {        @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE", "INVISIBLE_MEMBER")        monitorExit(lock)    }}

这里边也是有monitorEnter和monitorExit的,所以做出推测,不管synchronized是java中的关键字还是kotlin中的函数,最终被编译成的字节码是一样。

相关推荐