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
当我运行代码时,我发现这是因为我试图启动一个已经启动的线程。所以,我怎么能每次都终止或停止线程,来绕过这个问题呢?
7条答案
按热度按时间ipakzgxi1#
线程池可用于传递任务以设置线程数。启动时,设置线程数。然后为池添加任务。之后,您可以阻止,直到所有任务都已完成处理。下面是一些示例代码。
vuktfyat2#
为什么再次调用thread.start时会发生illegalthreadstateexception
因为jdk/jvm实现者
Thread.start()
方法就是这样。在线程完成执行后能够重新启动线程是一个合理的函数期望,这也是chrisbunney的答案中建议的(我在这个答案中加了一个注解),但是如果你看Thread.start()
实施,第一条线是,哪里
threadStatus == 0
手段NEW
所以我的猜测是,在执行完成后,实现不会将这个状态重置为零&线程处于空闲状态TERMINATED
状态(非零状态)。所以当你创建一个新的Thread
示例在同一个Runnable
,你基本上把这个状态重置为零。另外,我注意到在某些操作系统上,phan van linh指出了-may&never这个词在同一段落中的用法,因为不同的行为,
多次启动线程是不合法的。特别是,线程一旦完成执行,就不能重新启动。
我猜他们在上面的javadoc里想说什么,即使你不明白
IllegalThreadStateException
在某些操作系统上,以java/thread类的方式是不合法的&您可能会得到意外的行为。著名的线程状态图描述了相同的场景-没有从死状态回到新状态。
enyaitl33#
在android中,文档仍然提到
IllegalThreadStateException if the thread was already started
.但是对于某些设备,它不会抛出此异常(在kyocera 7.0上测试)。在一些流行的设备,如三星,宏达电,它抛出异常正常
我在这里回答是因为android问题被标记为这个问题的副本。
oxalkeyp4#
我一点也不确定我是否理解这个问题。所有停止从其他线程执行的线程的方法都已弃用;停止线程的方法是让它检查一个它和另一个线程可以访问的变量(可能是一个易失性变量),并让正在运行的线程偶尔检查它,看它是否应该自己退出。
我不知道为什么/是否要删除正在运行的线程并使用另一个线程,我也不知道不同的线程将如何帮助更快地执行您的总体目标。但有可能我只是不懂数学。
uxh89sit5#
isalive()方法可以告诉您线程是否已经启动。只需在要开始线程的位置执行以下操作:
cs7cruho6#
我怎样才能每次都终止或停止线程,从而绕过这个问题?
答案是,你不能。一旦开始,一个
Thread
可能无法重新启动。javadoc中清楚地记录了这一点Thread
. 相反,你真正想做的是new
一个例子RemoveNonPrime
每次你在你的圈子里转过来。代码中还有一些其他问题。首先,你需要增加
p
再次使用前:其次,您可能是多线程的,但不是并发的。您的代码基本上只允许一次运行一个线程:
只是我的$0.02,但是您正在尝试的操作可能会起作用,但是选择下一个最小素数的逻辑并不总是选择一个素数,例如,如果其他线程之一尚未处理数组的该部分。
下面是一个使用executorservice的方法,您需要填写一些空格(…):
8wtpewkr7#
您可以改为实现runnable并使用新线程($runnable here).start()或使用executorservice重用线程。