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中的函数,最终被编译成的字节码是一样。