2013-02-20 46 views
1

我試圖確定以下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)可能看不到item陣列的更新,並且返回null。這可能嗎?有什麼方法可以測試其安全性嗎?

+1

如果有疑問,並且您需要將該數組作爲容器傳回對象,則始終可以使用AtomicReference。我已經養成了將它用作通用容器的習慣,以便從匿名回調(和類似的ocasion)中傳回結果,即使我不需要原子方面。 – Durandal 2013-02-20 18:41:10

回答

1

由於如何invokeAndWait實施的細節,所有的行動中Runnable發生的發生,前控制到invokeAndWait調用者返回:

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

換句話說,你在做什麼是安全的。另一方面,沒有辦法通過測試來確保這樣的保證:)

1

數組不是自動線程安全的任何超過非final實例字段是。

但是,這裏沒有線程安全問題。在EventQueueinvokeAndWait內的分配與該方法返回之間將會有發生之前

注意invokeAndWait容易引起(有效)的死鎖。使用EventQueue.invokeLater和類似的方法回發到非EDT線程會更好。