synchronized在java中是一个关键字,但是在kotlin中是一个内联函数。假如分别在java和kotlin代码锁住同一个对象,会发生什么呢,今天写了代码试了试。
首先定义people类
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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
1 2 3 4 5 6 7 8 9 10
| class MyKotlinClass(private val people: People) { fun startThread() { Thread(Runnable { synchronized(people) { people.doSomething() }
}, 大专栏 对kotlin和java中的synchronized的浅谈g">"kotlin").start() } }
|
最后在main函数中执行如下代码
1 2 3 4 5 6
| fun main(args: Array<String>) { val people = People()
MyJavaClass(people).startThread() MyKotlinClass(people).startThread() }
|
观察输出结果是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 在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函数
1 2 3 4 5 6 7 8 9 10 11 12
| .internal.InlineOnly public 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中的函数,最终被编译成的字节码是一样。