gpt4 book ai didi

java - 使用匿名可运行类代码进入死锁状态,但使用 lambda 可以正常工作

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

我正在尝试找出下面提到的代码背后的原因。在这里,如果我使用匿名内部类创建 Thread,它会进入死锁状态,但使用 lambda 表达式它可以正常工作。我试图找到这种行为背后的原因,但找不到。

public class ThreadCreationTest {

static {
new ThreadCreationTest();
}

private void call() {
System.out.println("Hello guys!!!");
}

public ThreadCreationTest() {

// when we use this thread it goes in deadlock kind of state
Thread thread1 = new Thread(new Runnable() {
public void run() {
call();
}
});

// This one works fine.
Thread thread = new Thread(() -> call());

thread.start();
try {
thread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}

public static void main(String... args) {
System.out.println("Code finished...");
}
}

使用 lambda 表达式输出:

Hello guys!!!
Code finished...

匿名类:

code goes into deadlock state

最佳答案

使用 javap 反编译内部类显示以下 run 方法:

public void run();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #12 // Field this$0:Ltest/ThreadCreationTest;
4: invokestatic #22 // Method test/ThreadCreationTest.access$0:(Ltest/ThreadCreationTest;)V
7: return
LineNumberTable:
line 31: 0
line 32: 7
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 this Ltest/ThreadCreationTest$1;

请注意,有一个静态合成方法 access$0 依次调用私有(private)方法 call。创建合成方法是因为call是private的,对于JVM而言,内部类只是一个不同的类(编译为ThreadCreationTest$1),无法访问调用

static void access$0(test.ThreadCreationTest);
descriptor: (Ltest/ThreadCreationTest;)V
flags: ACC_STATIC, ACC_SYNTHETIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #68 // Method call:()V
4: return
LineNumberTable:
line 51: 0
LocalVariableTable:
Start Length Slot Name Signature

由于合成方法是静态的,它正在等待静态初始化器完成。但是,静态初始化程序正在等待线程完成,因此导致死锁。

另一方面,lambda 版本不依赖于内部类。构造函数的字节码依赖于使用 MethodHandlesinvokedynamic 指令(指令 #9):

public test.ThreadCreationTest();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=1
0: aload_0
1: invokespecial #13 // Method java/lang/Object."<init>":()V
4: new #14 // class java/lang/Thread
7: dup
8: aload_0
9: invokedynamic #19, 0 // InvokeDynamic #0:run:(Ltest/ThreadCreationTest;)Ljava/lang/Runnable;
14: invokespecial #20 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
17: astore_1
18: aload_1
19: invokevirtual #23 // Method java/lang/Thread.start:()V
22: aload_1
23: invokevirtual #26 // Method java/lang/Thread.join:()V
26: goto 36
29: astore_2
30: invokestatic #29 // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
33: invokevirtual #33 // Method java/lang/Thread.interrupt:()V
36: return

关于java - 使用匿名可运行类代码进入死锁状态,但使用 lambda 可以正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40241074/

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