
一度質問したことですが、再度質問させていただきます。
過去の質問は以下です。
http://oshiete1.goo.ne.jp/qa5528714.html
過去の質問を参考に、以下のように実装しました。
public class TEST{
public boolean testMe(){
Runnable runnable = /* 省略 */;
Thread thread = new Thread(runnable);
boolean alive = thread.isAlive();
/* 必ずfalseになってしまう */
if(!alive){
thread.start();
return true;
}
return false;
}
}
public class TEST2 implements Runnable{
public void run(){
/* 処理 */
}
}
上記の通りだと「thread.isAlive()」が必ずfalseで返ってきます。
また、Executorを利用した実装も試しました。
/* 処理を省略 */
ExecutorService executorService = Executors.newSingleThreadExecutor();
Runnable runnable = /* 省略 */;
// シャットダウン結果
boolean exeShutdown = executorService.isShutdown();
/* 一度シャットダウンすると、ずっとtrueになってしまう */
if(!exeShutdown){
// 実行
executorService.execute(runnable);
// シャットダウン
executorService.shutdown();
}
一度は実行されるのですが、
その後は「executorService.isShutdown()」がtrueしか返しません。
なので、一度しか実行できません。
再度、知恵を貸していただければと思います。
よろしくお願い致します
No.5ベストアンサー
- 回答日時:
元の質問には「「一度ボタンを押してスレッドが実行中の場合は処理を実行しない」という処理を実装したい」と書かれていますが、これは
(a) 実行中のスレッドが終了するまでは、何度ボタンを押しても単に無視する
(b) スレッド実行中にボタンが押された場合は、新しいスレッドを作るが今実行中のスレッドが終了するまで処理開始を遅らせる
のどちらでしょうか?
(a)だったら、最後に作ったスレッドを覚えておく変数を用意すればいいだけ。
public class TEST {
private static Thread lastThread = null;
public boolean testMe() {
if (lastThread != null && lastThread.isAlive()) {
return false;
} else {
Thread newThread = new Thread(...);
newThread.start();
lastThread = newThread;
return true;
}
}
(b)だったら、一番手抜きな方法はrun()メソッドの中身を全て排他処理にしてしまうこと。これなら、run()の内容を2つ以上のスレッドが同時に実行することができません。
public class TEST2 implements Runnable {
private static Object lock = new Object();
public void run() {
synchronized (lock) {
/* 処理 */
}
}
}
この回答への補足
独自に実装した処理でも出来ました。
しかし、あまり見栄えが良くなかったので、salsberry様の処理を使用させていただきます。
回答くださった皆様、この場を借りて、再度お礼いたします。
回答ありがとうございました。
回答ありがとうございます。
私の求めている実装は(a)です。
書いていただいた処理を試してみます。
余談ですが、独自に実装した処理で、何とか出来そうな感じがしています。
No.4
- 回答日時:
thread.start()をif文で、囲んでも意味ないような!!
thを5秒生きさせ、10秒後生きているかどうかの確認
Thread th = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(goo_test10.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
th.start();
System.out.println(th.isAlive());
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
Logger.getLogger(goo_test10.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(th.isAlive());
実行結果
true
false
回答ありがとうございます。
threadを5秒生きさせた場合、5秒以内にボタンを連打するとthreadが実行されないでしょうか。
しかし、これを応用すれば実装できそうな気がします。
No.3
- 回答日時:
こういうものを作ったらどお?
クラス名ThreadManager(シングルトン)
メソッド
・synchronized add(Thread)
新規スレッドを実行したくなったらThreadManagerにaddする。
・start
ThreadManagerに管理されているThreadを順に実行する。
1つ実行し終わったとき、管理されている次のThreadがあったらそれを実行
終わったThreadはThreadManagerから削除する。
こんなものを用意すればきっとうまいこといけるはずよ。
回答ありがとうございます。
「ThreadManagerにaddする」が、どのようなものか、いまいち不明です。
何かthreadに追加する実装があるのでしょうか。
「synchronized」や「addする」等を使用することで出来るようなので試してみます。
No.2
- 回答日時:
共有変数使えばいいんじゃないかと思うんですけど、、、
isAliveは
http://www.wakhok.ac.jp/biblion/1996/JavaAppli/n …
>スレッドが起動されて、かつ、ストップされていなければ、 trueを返します。
つまり、実行可能状態にあればTRUEを返すわけですから、
>/* 必ずfalseになってしまう */
これは当たり前の話では? (生成された直後は実行可能状態ではないのでは?)
isAliveは直ちに値を返すので、この関数で待とうとするとポーリングする必要が出てきますよね。これはスレッドプログラミングとしてはヘタクソなやり方だと思います。
そもそも1スレッドしか起こさないなら最初からマルチスレッドにする必要はないと思います。ライトウェイトとはいえコンテクストスイッチングにはコストが掛かりますので。
練習の意味でというならセマフォとかミューテックスで待ち合わせるべきと思います。それではメインがスタックして困るというなら、それはスレッドの分割の仕方が悪いのか、アーキテクチャの「ねり」が足りないのでは? Javaがどこまでサポートするのか知らないのですけど、キューなどの機構も考えてみては?
この回答への補足
回答ありがとうございます。
isAliveはstart後でなければtrueにならないのですね。
共有変数とは
Thread thread = null;
public boolean testMe(){
/* 省略 */
if(thread == null){
thread.start();
return true;
}
return false;
}
上記のようなことでしょうか?
上記である場合は、Executorと同じく一度実行すると二度と実行されません。
そもそも、
「runメソッドの処理が実行中の場合に、スレッドを実行するとrunメソッドの処理は実行されない」
ということは可能なのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 引数 戻り値のあるメソッド 3 2023/02/12 06:23
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
- Visual Basic(VBA) 【変更】ファイルを閉じてダイアログで保存した時、更新したシートだけの処理の実行をする 5 2022/03/26 18:31
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- Visual Basic(VBA) 【追加】ファイルを閉じてダイアログで保存した時だけ処理の実行をする 3 2022/03/23 15:43
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Java javaのクラスの分け方について質問です。 APIの内部用と外部用でクラスを分けたいのですがインター 2 2022/04/26 16:06
- PHP アップロード画像数でCSSを分けることに成功したのですが、画像の横に文字を並べることが出来ません。 3 2023/07/28 17:16
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
onBlurとonFocusの処理順序につ...
-
jQueryでdiv作成後まで待ってか...
-
Javaプログラムから外部コマン...
-
JSP、サーブレットの初期処理
-
do - while文
-
Tomcatのスレッドを破棄する方法
-
ftp 同時複数接続の負荷テスト...
-
アコーディオンメニューをアン...
-
wait()したスレッドが起こされ...
-
ServletContextLisntener#conte...
-
tryの終了
-
Javaプログラムからポップアッ...
-
doGetとdoPostの違い
-
表示待ち時間に「処理中...」の...
-
Windowsサービスの処理
-
重い処理中のアニメーションgif...
-
「スレッド」の概念について質問
-
重たい処理のタイムアウト強制終了
-
「タイプ初期化子が例外をスロ...
-
「隣の芝生は青く見える」現象...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
tryの終了
-
Tomcat高負荷時の設定について
-
Javaプログラムからポップアッ...
-
Javaでのデバッグコード削除
-
アコーディオンメニューをアン...
-
C#で別スレッドの終了を知りたい
-
onBlurとonFocusの処理順序につ...
-
Javaアプリケーション実行の返...
-
JavaScriptからJAVAクラスを呼...
-
表示待ち時間に「処理中...」の...
-
ExcelVBA で文字列の特定の文字...
-
C#の処理をリアルタイムに表示...
-
ラジオボタンの選択判定
-
Javaの再帰でメソッド呼び出す...
-
数値の定数を付ける時
-
[Java] while(true)の意味
-
Javaプログラムから外部コマン...
-
WaitForSingleObjectの復帰時間
-
Tomcatのスレッドを破棄する方法
-
重い処理中のアニメーションgif...
おすすめ情報