为什么再次调用Thread.start时会发生IllegalThreadStateException

public class SieveGenerator{ static int N = 50; public static void main(String args[]){ int cores = Runtime.getRuntime().availableProcessors(); int f[] = new int[N]; //fill array with 0,1,2...f.length for(int j=0;j<f.length;j++){ f[j]=j; } f[0]=0;f[1]=0;//eliminate these cases int p=2; removeNonPrime []t = new removeNonPrime[cores]; for(int i = 0; i < cores; i++){ t[i] = new removeNonPrime(f,p); } while(p <= (int)(Math.sqrt(N))){ t[p%cores].start();//problem here because you cannot start a thread which has already started(IllegalThreadStateException) try{ t[p%cores].join(); }catch(Exception e){} //get the next prime p++; while(p<=(int)(Math.sqrt(N))&&f[p]==0)p++; } //count primes int total = 0; System.out.println(); for(int j=0; j<f.length;j++){ if(f[j]!=0){ total++; } } System.out.printf("Number of primes up to %d = %d",f.length,total); } } class removeNonPrime extends Thread{ int k; int arr[]; public removeNonPrime(int arr[], int k){ this.arr = arr; this.k = k; } public void run(){ int j = k*k; while(j<arr.length){ if(arr[j]%k == 0)arr[j]=0; j=j+arr[k]; } } } 

嗨,当我运行我的代码时,我得到一个IllegalThreadStateException ,我认为这是因为我正在尝试启动一个已经启动的线程。 那么我怎么能每次杀死或停止线程来解决这个问题呢?

我怎么能每次杀死或停止线程,以解决这个问题?

答案是,你做不到。 一旦启动, Thread可能无法重新启动。 这在Thread的javadoc中有明确记载。 相反,你真正想要做的是每次循环时都使用RemoveNonPrime new实例。

您的代码中还有其他一些问题。 首先,您需要在再次使用之前递增p

 for(int i = 0; i < cores; i++){ t[i] = new removeNonPrime(f,p); //<--- BUG, always using p=2 means only multiples of 2 are cleared } 

其次,您可能是multithreading的,但您不是并发的。 您拥有的代码基本上只允许一次运行一个线程:

 while(p <= (int)(Math.sqrt(N))){ t[p%cores].start();// try{ t[p%cores].join(); //<--- BUG, only the thread which was just started can be running now }catch(Exception e){} //get the next prime p++; while(p<=(int)(Math.sqrt(N))&&f[p]==0)p++; } 

只是我的0.02美元,但你想要做的可能会工作,但选择下一个最小素数的逻辑并不总是选择素数,例如,如果其他一个线程尚未处理该arrays的那部分。

以下是使用ExecutorService的方法,您需要填写一些空白(...):

 /* A queue to trick the executor into blocking until a Thread is available when offer is called */ public class SpecialSyncQueue extends SynchronousQueue { @Override public boolean offer(E e) { try { put(e); return true; } catch (InterruptedException ex) { Thread.currentThread().interrupt(); return false; } } } ExecutorService executor = new ThreadPoolExecutor(cores, cores, new SpecialSyncQueue(), ...); void pruneNonPrimes() { //... while(p <= (int)(Math.sqrt(N))) { executor.execute(new RemoveNonPrime(f, p)); //get the next prime p++; while(p<=(int)(Math.sqrt(N))&&f[p]==0)p++; } //count primes int total = 0; System.out.println(); for(int j=0; j 

您可以实现Runnable而使用新的Thread($ Runnable here).start()或使用ExecutorService来重用线程。

ThreadPools可用于传递任务以设置线程数。 启动时设置线程数。 然后,您为池添加任务。 并且在您可以阻止所有任务完成处理之后。 这是一些示例代码。

我完全不确定我理解这个问题。 不推荐使用从其他线程执行的所有停止线程的方法; 停止线程的方法是让它检查它和另一个线程可以访问的变量(可能是一个volatile变量),并让正在运行的线程偶尔检查一下它是否应该自行退出。

我不知道为什么/是否要消除正在运行的线程并使用另一个线程,我无法看到不同线程如何更快地帮助执行您的总体目标。 但是我可能只是不理解数学。

Thread.isAlive()方法可以告诉您线程是否已经启动。 只需在您想要启动线程的地方执行此操作:

  if(!t[p%cores].isAlive()){ t[p%cores].start(); } 
 * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception IllegalThreadStateException if the thread was already started */ public synchronized void start() { 

在Android中,文档仍然提到IllegalThreadStateException if the thread was already started ,我们将获得IllegalThreadStateException if the thread was already started
但是对于某些设备,它不会抛出此exception(在Kyocera 7.0上测试)。 在像三星,HTC这样的流行设备中,它通常抛出exception

我在这里回答是因为Android问题标记为与此问题重复。