2011-04-11 59 views
7

每當我開始我的線程時,我總是做這個檢查。我沒有在任何地方發現我叫上線開始沒有做下面Java線程錯誤IllegalThreadState線程已經開始

if (!myThread.isAlive()) 
    myThread.start(); 

儘管如此檢查,我結束了IllegalThreadStateException:主題已經開始。這實際上崩潰了我的應用程序(android)。那麼在啓動一個線程之前,我還需要做一些其他的檢查嗎?

+3

線程可能不活動並且仍然已經啓動:即它可能已經啓動並且已經完成。也許在這裏呢? – pajton 2011-04-11 22:33:46

+0

如果兩個線程共享對myThread的引用,那麼他們都可能檢查myThread.isAlive(),並且都看到false,然後它們都嘗試啓動。你可能不應該像這樣啓動線程(傳遞一個Thread對象,以後啓動)。您應該使用java.util.concurrent.Executors中的ExecutorService。如果您發佈有關線程正在執行的更多詳細信息,則可以提供更具體的建議。 – 2011-04-11 22:35:28

回答

3

您是否使用new爲myThread引用創建了一個新實例? 您只能在單個實例上執行一次myThread.start()。

檢查它是否存在不是正確的方法。創建一個新的實例。

11

你應該檢查線程是否已經開始使用getState()並且只有在它的state is NEW時才啓動,否則創建新線程(如果需要的話)。

+2

讓我澄清這種方法。如果(thread.getState()== Thead.State.NEW) – Androider 2011-04-12 01:18:11

+0

then thread.start() – Androider 2011-04-12 01:18:28

+0

那麼如果任何其他狀態,然後創建一個新的線程? – Androider 2011-04-12 01:19:17

0

我剛剛在這裏有類似的情況,這就是爲什麼我給出了一個遲到的答案。

問題是,您的解決方案Thread.isAlive()Thread.start()不是多線程安全的。它可能發生在第一個線程調用您的代碼,執行isAlive()Thread.start()內某處,在新線程啓動之後並且狀態更改之前,發生任務切換,並且第二個調用程序在仍然false時執行isAlive(),從而使start()被調用兩次。爲了讓它在start()內部變得更糟,似乎任務開關被強制,因此這個問題經常出現。

解決方案:覆蓋start(),使其多線程安全的,例如

private final AtomicBoolean started = new AtomicBoolean(false); 
/* (non-Javadoc) 
* @see java.lang.Thread#start() 
*/ 
@Override 
public synchronized void start() { 
    if (!started.getAndSet(true)) { 
     super.start(); 
    } 
} 

那麼不會出現你的問題更多,即使start()不慎被調用了兩次。