[解決済み] Thread.startを再度呼び出すとIllegalThreadStateExceptionが発生するのはなぜか
2022-02-07 09:41:54
質問
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
. その代わり、本当にやりたいことは
new
のインスタンスです。
RemoveNonPrime
ループの中で回ってくるたびに
あなたのコードには、他にもいくつかの問題があります。
まず
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
}
次に、マルチスレッドかもしれませんが、同時並行処理ではありません。あなたのコードは、基本的に一度に1つのスレッドしか実行できません。
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++;
}
しかし、次に小さい素数を選択するロジックは、例えば、他のスレッドがまだ配列のその部分を処理していない場合、常に素数を選択するわけではありません。
ExecutorService を使用したアプローチを紹介します。いくつかの空白(...)を埋める必要があります。
/* A queue to trick the executor into blocking until a Thread is available when offer is called */
public class SpecialSyncQueue<E> extends SynchronousQueue<E> {
@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<f.length;j++){
if(f[j]!=0){
total++;
}
}
System.out.printf("Number of primes up to %d = %d",f.length,total);
}
class RemoveNonPrime extends Runnable {
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+=k;
}
}
}
関連
-
[解決済み】代入の左手は必ず変数 CharAt
-
[解決済み】Android Studioでタスク :app:compileDebugJavaWithJavac の実行に失敗しました。
-
[解決済み】keytoolエラー 鍵屋が改ざんされたか、パスワードが不正確だった場合
-
[解決済み】文字列中の � を置換する方法
-
[解決済み】純粋なJUnitテストにVisibleForTestingを使用する方法
-
[解決済み】Javaの".class expected "について
-
[解決済み】接続Java - MySQL : 公開鍵の取得は許可されていません。
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み] なぜJavaにはtransientフィールドがあるのですか?
-
[解決済み] Math.round(0.4999999999994) はなぜ1を返すのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Android Studio クラス org.codehaus.groovy.runtime.InvokerHelper を初期化できませんでした。
-
[解決済み】imageio.IIOException: 入力ファイルが読み込めない
-
[解決済み】Javaの".class期待値"
-
[解決済み】Java、"変数名 "を変数に解決することができない
-
[解決済み】スレッド「main」での例外 java.lang.StringIndexOutOfBoundsException: 文字列のインデックスが範囲外です。0 [閉店]
-
[解決済み] メソッドがそのスーパークラスのメソッドをオーバーライドしない
-
[解決済み】JLabelのテキストを中央に配置するには?
-
[解決済み】Eclipseで「JUnitテストが見つかりませんでした。
-
[解決済み】javaで無効な文字定数
-
[解決済み】接続Java - MySQL : 公開鍵の取得は許可されていません。