gpt4 book ai didi

java - 同步表达式中的方法引用

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:44:06 25 4
gpt4 key购买 nike

对不起大家,但我不明白,sync() 方法内的哪个对象是 synchronized block 是同步的:

public class TestLambda {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}

static void sync() throws InterruptedException {
synchronized ((Runnable)TestLambda::new) {
System.out.println("inside");
Thread.sleep(1000L);
}
}
}

如果在方法引用对象上,为什么我不能只写:同步 (TestLambda::new) ? (这将是编译时错误)。

有什么想法吗?

UPD:以防万一:它是真正同步的

UPD-2:对于那些有疑问的人,简单的例子:

C:\sandbox\research\learn8\src>"C:\Program Files\Java\jdk1.8.0_31\bin\"javac TestLambda.java
TestLambda.java:27: error: method reference not expected here
public class Test { { synchronized (Test::new) { System.out.println("sync"); } } }
^
1 error

最佳答案

让我们看看下面的 2 个作业:

Supplier<TestLambda> supp = TestLambda::new;
Runnable runnable = TestLambda::new;

它们都编译得很好。主要是因为 lambda 或方法引用可以与多个功能接口(interface)兼容。这意味着,仅编写 TestLambda::new 并不能告诉我们所创建对象的确切运行时类型。要实例化哪个接口(interface)是根据目标类型确定的。并且该目标类型应始终是功能接口(interface),但在以下语句中不是这种情况:

synchronized(TestLambda::new) {
}

因此,编译器不允许这样做,因为运行时无法决定实例化哪个功能接口(interface)。您可以通过将方法引用强制转换为 Runnable 来提供该信息。所以,在下面的声明中:

synchronized((Runnable) TestLambda::new) {
}

运行时将实例化实现Runnable 接口(interface)的类的对象。从某种意义上说,转换为方法引用提供了具体性。

为了给出一个模糊的想法,这在某种程度上可以这样翻译:

class RuntimeClass implements Runnable {
public void run() {
TestLambda testLambda = new TestLambda();
}
}

synchronized(new RuntimeClass()) {
}

P.S:RuntimeClass 的实际实例将是单例的(因为我们使用的是无状态方法表达式)——我原来的错误陈述

P.P.S:正如@Stuart 的评论所述,无法保证对于 lambda 或方法引用,是否会创建新实例或返回相同的实例。所以,你不应该同步它们。

关于java - 同步表达式中的方法引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29439136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com