对kotlin和java中的synchronized的浅谈

Posted lijianming180

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对kotlin和java中的synchronized的浅谈相关的知识,希望对你有一定的参考价值。

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









































































































































































以上是关于对kotlin和java中的synchronized的浅谈的主要内容,如果未能解决你的问题,请参考以下文章

kotlin,为什么反编译java代码将同步锁定块转换为synchronized(var1){} +代码块?

Java回顾一下Java中的synchronized

java中的synchronized两种用法

请问java中的lock和synchronized区别是啥?

请问java中的lock和synchronized区别是啥?

从Java线程到kotlin协程之线程同步(wait)