- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我偶然发现了一个使用 invokeAndWait 的问题。下面的示例代码说明了这个问题。谁能详细说明发生了什么?为什么 lambda 表达式挂起而匿名内部类和方法 ref 没有挂起。
public class Test {
// A normal (non-static) initializer does not have the problem
static {
try {
System.out.println("initializer start");
// --- Works
System.out.println("\nanonymous inner-class: Print.print");
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
Print.print();
}
});
// --- Works
System.out.println("\nmethod ref: Print.print");
EventQueue.invokeAndWait(Print::print);
// --- Hangs forever
System.out.println("\nlambda: Print.print");
EventQueue.invokeAndWait(() -> Print.print());
System.out.println("\ninitializer end");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Test();
}
}
打印类:
public class Print {
public static void print() {
System.out.println("Print.print");
}
}
最佳答案
这是因为 lambda 表达式(部分)被编译为 Test
内部的方法,而方法引用和匿名内部类的方法则没有。
来自 Translation of Lambda Expressions :
When the compiler encounters a lambda expression, it first lowers (desugars) the lambda body into a method whose argument list and return type match that of the lambda expression, possibly with some additional arguments (for values captured from the lexical scope, if any.)
...
Method references are treated the same way as lambda expressions, except that most method references do not need to be desugared into a new method;
您可以通过查看编译类产生的字节码来验证这一点。
这很重要的原因是,当事件队列线程尝试执行通过对 lambda 主体进行脱糖创建的方法时,它会阻塞等待第一个线程完成初始化 Test
,并且这两个线程会陷入死锁.
section 12.4 中描述了初始化过程JLS 的:
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
- A static method declared by T is invoked.
...
If the Class object for C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this step.
也在 section 5.5 中JVMS 的:
Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.
参见 this question对于没有 lambda 的类似示例。
关于java - 带有 lambda 表达式的 invokeAndWait 在静态初始值设定项中永远挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34222669/
我有一个 MvvmCross MvxSpinner在 Android 中绑定(bind)。用户选择一个值并反射(reflect)在我的属性 MealTypeSelected . 微调器允许用户选择膳
我有一个带有某种类型函数指针的公共(public)变量的表单,如下所示: {...} interface type TExternalFunction = function(var x : TAn
this question中的答案对我理解如何在 IBAction 方法中检索步进器值很有帮助(我投了赞成票),但我仍然不理解在我第一次加载 View 时如何获取步进器的初始值。 我想将初始值设置为
Apple 文档指出: The willSet and didSet observers of superclass properties are called when a property is
我正在将 ColdFusion 应用程序转换为 C#(我是 CF n00b)。 我有一个脚本执行 cfquery,然后执行 cfloop 的结果,它似乎试图将当前行与其下一行进行比较。它似乎试图确保它
我在为 antd 动态表单设置初始值时遇到问题。有什么方法可以在动态中初始化值吗?它需要使用 getFieldDecorator 注册字段。但对于动态字段,该字段之前没有注册。 我收到这个错误:不能在
是否可以动态地为 forms.FileField() 赋予初始值? 最佳答案 我不确定,如果这就是你想要的,但是…… 显然,您不能为文件输入设置初始数据(这意味着您将文件发送给用户)。 Django
我对 Django 表单中 DateTimeField 的初始值没有什么问题。 我在 forms.py 中有声明 class FaultForm(forms.ModelForm): ...
如何使用代码设置 slider 初始值?我知道如何在属性检查器中执行此操作。我想在我的应用程序启动时使用“UserDefault”作为初始值,当我的应用程序第一次启动时,我想将初始值设置为“1.0”
我有一个 RadioButton其 IsChecked 的元素属性绑定(bind)到 MyProperty在 ViewModel . Binding有模式OneWayToSource由于某些原因,它会
我有一个ViewModel类,看起来像这样: class EditUserViewModel( private val initUser: User, ) : ViewModel() {
有人可以帮我解决我的问题吗,问题是我希望我输入到文本字段的第一个初始值只是从 1 到 9 的数字,我正在使用小数垫,所以我也不希望我的初始值是小数点,但在第一个值(仅从 1 t0 9 开始的数字)之后
我正在使用 NSFetchedResultsController 从 CoreData 获取数据并加载包含四个部分的 TableView 。当应用程序第一次运行时,它可以完美地工作,将 plist 加
使用 primeNg 下拉组件,我试图用初始值初始化下拉列表,但没有成功,我使用的是响应式(Reactive)方法。 我检查了 primeNg 文档和演示 - 几乎所有示例都使用模板驱动,我希望模型驱
如何在 ASP.NET 中设置数据绑定(bind)下拉列表的初始值? 例如,我想要这些值,但要显示的第一个值应该是 -- Select One ---,且值为空。 最佳答案 我想你想做的是这样的:
我知道我不能给 BehaviorSubject一个 Observable 值,但我需要一种方法来解决这个问题。在应用程序初始化时,我正在获取当前用户(如果存在),我需要提供 BehaviorSubje
这是我在这里的第一篇文章,所以我希望它是全面的。 我正在使用 AngularJs,并且我使用 Angular 指令添加了一个 JqueryUI slider 。我找到了很多关于如何做到这一点的例子,但
如何有效地为大型数组分配一个公共(public)初始值?例如,如果我有一个 100 x 100 x 100 的整数数组,其中所有初始值都应为零。 在 matlab 中我会简单地写: array = z
我正在为 iOS 应用程序创建一个 Pebble 配套应用程序。我已经使用一些初始值设置了我的 AppSync: Tuplet initial_values[] = { TupletC
有件事我迟到了: const [object, setObject] = useState(new SomeObject()); 在这里,我们在每次重新渲染上构造一个SomeObject实例。然后,如
我是一名优秀的程序员,十分优秀!