Java 在匿名类中使用数组是否线程安全?
我试图确定以下java方法是否是线程安全的:Java 在匿名类中使用数组是否线程安全?,java,thread-safety,Java,Thread Safety,我试图确定以下java方法是否是线程安全的: public Object calledByMultipleThreads() { final Object[] item = new Object[1]; if (!EventQueue.isDispatchThread()) { try { EventQueue.invokeAndWait(new Runnable() { @Override
public Object calledByMultipleThreads() {
final Object[] item = new Object[1];
if (!EventQueue.isDispatchThread()) {
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
helperMethod(item)
}
});
} catch (InterruptedException | InvocationTargetException ex) {
// logging...
}
} else {
helperMethod(item)
}
return item[0];
}
private void helperMethod(Object[] item) {
item[0] = new Object();
}
我知道
final Object[/item=new Object[1]
是一种变通方法(因为像final Object item
这样的东西不能在Runnable
中修改)。由于使用了invokeAndWait
,项[0]
在被返回
引用之前就被设置好了,但是我担心调用线程(不是EDT)可能看不到项
数组的更新,并且返回null
。这可能吗?有什么方法可以测试它的安全性吗?由于invokeAndWait
是如何实现的,在Runnable
中发生的所有操作都是在invokeAndWait
的调用者返回控制之前发生的:
1233 synchronized (lock) {1234 Toolkit.getEventQueue().postEvent(event);
1235 while (!event.isDispatched()) {
1236 lock.wait();
1237 }
1238 }
已同步(锁定){
工具包。(。)(事件);
而(!事件。){
锁定。;
}
}
换句话说,你所做的是安全的。另一方面,没有办法通过测试来确保这样的保证:)数组不会像非
final
实例字段那样自动实现线程安全
但是,这里没有线程安全问题。EventQueueinvokeAndWait
中的赋值与该方法返回之间将有一个before
注意
invokeAndWait
容易导致(有效)死锁。最好使用EventQueue.invokeLater
和类似的方法发回非EDT线程。当有疑问时,并且当您需要数组作为容器来传回对象时,您可以始终使用AtomicReference。我已经养成了习惯,将它作为一个通用容器来传递匿名回调(和类似的局部调用)的结果,即使我不需要原子方面。