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中的函數,最終被編譯成的字節碼是一樣。