在匿名类线程中使用数组是否安全?

时间:2013-02-20 18:16:15

标签: java thread-safety

我正在尝试确定以下java方法是否是线程安全的:

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之类的内容无法修改。由于使用invokeAndWaititem[0]在被return引用之前设置,但我担心调用者线程(不是EDT)可能看不到对{的更新{1}}数组,并返回item。这可能吗?有什么方法可以测试它的安全性吗?

2 个答案:

答案 0 :(得分:1)

由于invokeAndWait的实施方式的详细信息,Runnable 内发生的所有操作都发生在控制权返回invokeAndWait的来电之前:

1233  synchronized (lock) {
1234 Toolkit.getEventQueue().postEvent(event);
1235 while (!event.isDispatched()) {
1236 lock.wait();
1237 }
1238 }

换句话说,你所做的是安全的。另一方面,通过测试无法确保这样的保证:)

答案 1 :(得分:1)

阵列不是自动线程安全的,而不是非final实例字段。

但是,这里没有线程安全问题。在EventQueueinvokeAndWait内的分配和返回的方法之间会有发生在之前。

注意invokeAndWait可能导致(有效)死锁。最好使用EventQueue.invokeLater和类似方法回发到非EDT主题。