• ベストアンサー

Thread処理について、教えてください!

はじめまして、いきなりですが質問させて頂きます。 sleep()メソッドは、Threadクラスのクラスメソッドであるため、 Thread.sleep();と書けば、main()メソッドの処理を一時停止できると 書いていました。 sleep();と書けば、Threadのrun()メソッドが一時停止するのはわかりますが、なぜ、sleep();にThread.を付けたらmain()メソッドが停止するのかわかりません。 なぜなのか、簡単に教えてください。

  • Java
  • 回答数4
  • ありがとう数7

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

こんばんは。 http://sdc.sun.co.jp/java/docs/j2se/1.5.0/ja/docs/ja/api/java/lang/Thread.html#sleep(long) によれば、 >public static void sleep(long millis) throws InterruptedException >現在実行中のスレッドを、指定されたミリ秒数の間、スリープ (一時的に実行を停止) させます。スレッドはモニターの所有権を失いません。 だし、Java 6 の Thread.Sleep http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/Thread.html#sleep(long) を読んでも、やっぱり static メソッド(クラスメソッド)で、現在実行中のスレッドが対象だから、 Thread.sleep(); は sleep(); とは書けないと思います。 だから、 >なぜ、sleep();にThread.を付けたらmain()メソッドが停止するのかわかりません。 において、Threadをつけることで、sleep();の実行対象が main になるという認識が誤り。 RunnableインターフェースをImplementし、run メソッドを実装したクラスを、インスタンス化して、start(); すれば、スレッド起動されるが、スレッド起動されたクラスにおいても、自分自身を止めるには、sleep(); ではなく、Thread.Sleep(); と書きます。 ここがわかりやすいかな。 http://www.nextindex.net/java/thread/sleep.html マルチスレッドの考え方はあってます。 シングルスレッドとは、 public static void main(String[] args) で書いたmainメソッドも、Java仮想マシンがスレッド実行しており、この中でスレッドを生成していないなら、スレッドは1つしかない(mainメソッド)という意味。このとき、mainメソッドに、Thread.sleep();と書けば、mainメソッドの実行が止まる、ということですね。 Java 5.0のAPIリファレンスを参考URLにつけといたので熟読してください。:-)      

参考URL:
http://sdc.sun.co.jp/java/docs/j2se/1.5.0/ja/docs/ja/api/index.html
rescue99
質問者

お礼

ありがとうござます! JavaTM 2 Platform Standard Edition 5.0 API 仕様のことをリファレンスと言うのですね。 コンストラクタ、メソッドの使い方はわかりますが、入れ子のクラス・フィールドの使い方がわかりません。 スレッドに設定できる最高優先順位の付け方とかさっぱりです。 MAX_PRIORITY このリファレンスを見て、理解できるほど読解力がまだ備わっていないようです。 入れ子のクラスとか意味がわかりません。使い道も。。

その他の回答 (3)

回答No.4

こんばんは。#2です。 お礼いただきありがとうございます。 ご返信の内容かすると、比較的難解であるJavaのマルチスレッドプログラミングではなく、まず、市販の入門書などで、Javaの基本を勉強されたようがよいような気がします。こちらがおすすめです。 http://www.amazon.co.jp/exec/obidos/tg/detail/-/4797331828/ref=cm_lm_fullview_prod_1?_encoding=UTF8&v=glance >JavaTM 2 Platform Standard Edition 5.0 API 仕様のことをリファレンスと言うのですね。 リファレンスマニュアルというのは、言語における”キーワード”を個別に詳細に説明したものです。Javaであれば、クラス、メソッドの説明になります。reference=参照ですから、辞書のように、いつも手元においておくもの。プロのプログラマーであっても、すべてのクラスやメソッドを知っているわけではありません。 >コンストラクタ、メソッドの使い方はわかりますが、入れ子のクラス・フィールドの使い方がわかりません。 >入れ子のクラスとか意味がわかりません。使い道も。。 というご返信は、(あなたがそういうつもりであったとしても)この質問からは論点がずれてしまっていますね。少々、厳しい言い方ですが、Thread.Sleepの話を理解したのかも、書いてないですし。 老婆心ながら、入れ子クラスの用途は、外部のクラスから、内部のやりとりを隠蔽できる/パブリックなクラスにするほどでもないクラスを内部で定義して、プログラムのわかりやすさを高める/クラスファイルが増えない、などの利点がありますが、入門レベルではインナークラスの必要性について考える必要はありません。 ともかく、リファレンスを使えるようになるためには、Java言語を理解している必要があります。言語の修得は、とりあえず、やってみることが非常に重要ではありますが、言語仕様を理論的に整理する段階にあるような気がします。前述の書籍などで学ばれるか、新しい質問を起こすなどして、対応しましょう。(^^)      

rescue99
質問者

お礼

Thread.Sleepは理解できました。ありがとうございます。 やさしいJavaを読みました。 東大卒の女の方ですごいと思いました。 いまは立て続けにやさしいJava活用編を読んでいます。 もうちょっとJavaを知ってからリファレンスを読解したいと思います。 ありがとうございました!! この質問は締め切らせて頂きます。

  • yaguma
  • ベストアンサー率57% (4/7)
回答No.3

Thread.sleep()メソッドは、そのメソッドを呼び出したスレッドを一時停止させる機能を持っています。 main()メソッドも、メインスレッドというひとつのスレッドによって実行されますので、main()内部でThread.sleep(1000)と記述した場合、メインスレッドの実行を一時停止させることができます。 >sleep();と書けば、Threadのrun()メソッドが一時停止するのはわかりますが >なぜ、sleep();にThread.を付けたらmain()メソッドが停止するのかわかりません。 sleep()メソッドの呼び出し方による違いに混乱されてるようですが、sleep()と書こうとThread.sleep()と書こうと機能はまったく同じです。 問題は、どのスレッドによって呼び出されるかです。 例えば、以下のコードのsleep()メソッドをThread.sleep()に書き換えたからといって、動作は変わりません。どちらも同じように、このrunメソッドを実行しているスレッドを一時停止させます。 /* Threadクラスのrun()メソッドをoverride */ public void run(){ System.out.println("thread-start"); try{ sleep(1000); //Thread.sleep(1000); }catch(InterruptedException e){ } System.out.println("thread-end"); }

rescue99
質問者

お礼

ありがとうござます! JavaTM 2 Platform Standard Edition 5.0 API 仕様のことをリファレンスと言うのですね。 コンストラクタ、メソッドの使い方はわかりますが、入れ子のクラス・フィールドの使い方がわかりません。 スレッドに設定できる最高優先順位の付け方とかさっぱりです。 MAX_PRIORITY このリファレンスを見て、理解できるほど読解力がまだ備わっていないようです。 入れ子のクラスとか意味がわかりません。使い道も。。

  • com58
  • ベストアンサー率37% (3/8)
回答No.1

J2SEのリファレンスはご覧になったでしょうか? sleep()はメソッドを止めるのではなく、現在実行中のスレッドを休止させるものです。リファレンスにもそう記述してあります。 ご質問の状況ではシングルスレッドのプログラミングとなっていて、そのため、sleep()でメインスレッドを休止させているのではないかと思われます。 一度隅々までリファレンスを読んでみてはいかがでしょうか。

rescue99
質問者

お礼

ありがとうござます! リファレンスを見て勉強してます。 一時停止なので、sleep(1000);と書けば、1秒後にrun()メソッドが再開されます。 Thread.sleep(1000);と書けば、1秒後にmain()メソッドが再開されます。 スレッドを生成した時点でmain()メソッドからrun()メソッドが平行して実行されるので、 スレッド=マルチスレッドではないのですか? ???シングルスレッドとはなんでしょうか??? Thread.sleep(1000);で、なぜmain()メソッドが休止するのか知りたいのですorz

rescue99
質問者

補足

↓の回答へのお礼で、リファレンスを見て勉強していると書きましたが、正しくはJ2SEのリファレンスではなく、 Sun MicrosystemsにあるThe Java Tutorialsというページで勉強してましたorz J2SEのリファレンスのURLを教えて頂けたらうれしいです!お願いします!

関連するQ&A

  • Thread.sleep()はすべてのスレッドを停止する?

    Threadを継承したCarというインスタンスを5つ作ってstart()させたとします。 そのあと、クラスメソッドのThread.sleep(1000)をすると、すべてのThreadインスタンスが1秒止まるのかと思ったのですが、そうではないといわれました。 クラスメソッドのThread.sleep()は何をsleepさせるのでしょうか?

    • ベストアンサー
    • Java
  • Threadのrun()メソッドについて

    Threadのrun()メソッドについて質問です。 run()メソッドは処理が完了すると自然消滅しますか?

    • ベストアンサー
    • Java
  • スレッドについての質問です。

    下記のロジックを見ていただきたいのです。 スレッドがnullの間はrunが動いています。 問題は一番下に記載した"stopplay()"というメソッドだと思われます、スレッドを停止して直ぐにまた動かしていますがどうもスレッドが二つ動いている様子です。なぜでしょうか? ************************************************** //最初にスレッドを開始します。 public init(){ play(); } ************************************************** //スレッドのON OFF public void threadOnOff(boolean sw) { if(sw == true){ thread =new Thread(this); thread.start(); } else { thread = null; } } ************************************************** //スレッド開始 public void play(){ threadOnOff(true); } ************************************************** //スレッド停止 public void stop(){ threadOnOff(false); } ************************************************** //runメソッド  public void run(){ String mode = ""; while(thread != null){ try { thread.sleep(500); //0.5秒間隔で動きます。 mode = modeRequest(); if(mode.startsWith("STOP") == true) { //スレッド停止 threadOnOff(false); } } catch (InterruptedException ie) {} } } ************************************************** //問題のメソッドです。 public void stopplay(){ stop(); play(); }

    • ベストアンサー
    • Java
  • Thread.sleep()について(休止の対象は)。

    こんにちは。 Javaで、 Thread.sleep(duration);と書いた場合、 停止の対象となるスレッドは どうなるのでしょうか。 もし、sleep()がインスタンスから、 呼び出せるなら、thread(インスタンス).sllep() と書くことで、そのインスタンス(スレッドを 継承したクラス)を休止するので、 分かりやすいのですが、Thread.sleep()と 書くので、わかりずらいです。 以下のような、書き方に戸惑っています。 public class xx{ public static void main(String args){ while(1){ Thread.sleep(1000); System.out.println("abc"); } } } これは、 メインスレッドを対象としている、 と考えていいのでしょうか。 スレッドを継承したクラスで、 Thread.sleep()と書いたときは、 そのクラスを休止させる、 という理解で、いいのでしょうか。 何かアドバイスできる人がいましたら、 よろしくお願いします。

    • ベストアンサー
    • Java
  • Thread.Abortメソッド後の処理について

    Thread.abortメソッドについて分からないことがあったので,助言が頂けると嬉しいです. Thread.Abort () を発生させると,通常そこでスレッドが終了するということなので,その後のスレッド内の処理はスルーされると思っていたのですが,下記コードですとその後の pictureBox1.Image = null;も実行されている様です. mainでスレッド作成→threadAの停止になると考えていたのですが,delegate内では反映されないのでしょうか? Thread thread_a; //スレッド delegate void Del(); private void main(object sender, EventArgs e) { //スレッドを開始 thread_a = new Thread(new ThreadStart(threadA)); thread_a.Start(); } private void threadA() { new Thread(new ThreadStart(delegate { Invoke((Del)delegate { thread_a.Abort(); //画像を消去する pictureBox1.Image = null; }); })).Start(); }

  • Thread のターゲット切り替えについて

    以下のようなソースを書きました。Runnableを実装しているクラスをスーパークラスに持つクラスThreadSampleChildをインスタンス化した後にそのクラスのThreadを実行し、途中で親クラスのスレッドに切り替えることを目的としているのですが、切り替わらずに子クラスのThreadが引き続き継続してしまいます。 理由はなんとなくわかるのですが。子クラスから親クラスのThreadを実行させるためにはどう工夫すればよいのでしょうか? class ThreadSample implements Runnable { Thread threadp; ThreadSample() { } public void run() { while(true) { try { System.out.println("Parent"); Thread.sleep(500); } catch(Exception e) { break; } } } public void makingThreadParent() { threadp = new Thread(this); } } class ThreadSampleChild extends ThreadSample { Thread threadc; ThreadSampleChild() { } public void run() { while(true) { try { System.out.println("Child"); Thread.sleep(500); } catch(Exception e) { break; } } } public void makingThreadChild() { threadc = new Thread(this); } public void exe() { while(true) { threadc.start(); try { Thread.sleep(10000); } catch(Exception e) { } threadc.interrupt(); makingThreadParent(); System.out.println("Thread Change !!!!"); threadp.start(); try { Thread.sleep(10000); } catch(Exception e) { } threadp.interrupt(); } } public static void main(String args[]) { ThreadSampleChild tsc = new ThreadSampleChild(); tsc.makingThreadChild(); tsc.exe(); } }

    • ベストアンサー
    • Java
  • C++ Thread::Sleep()について

    RunTimer = gcnew Timer(); RunTimer->Interval = 50; RunTimer->Tick += gcnew EventHandler(this, &RunTick); RunTimer->Enabled = true; ・・・処理・・・ RunTimer->Enabled = false; System::Threading::Thread::Sleep(1000); としているのですが、数コマ動いてしまいます。 処理は3枚の画像を差し替えて動かしているのですが、即座にスリープがかからず、 画像が少し歪んでしまいます。 ソースが長く、どこを記載すれば良いのか解らず、かなり抜粋しましたが、 TimerのTickで画像を入れ替えて、歩いている様にみせかけています。 一時停止後、改めて処理を始めようと思っているのですが、 なぜだか、少し動いてしまします。 Sleepを削除すると、うまく止まるのですが、即座に次の処理に移行してしまう為、数秒停止させたいと考えています。 System::Threading::Thread::Sleep(1000); だけでは、即座に止める事はできないものでしょうか? また、TimerのTickを数秒止める事はできるものでしょうか? ご存じの方、アドバイスよろしくお願いいたします。

  • 非スレッドでsleepのように処理を指定時間止めるクラス・メソッドありませんか?

    現在、Struts、Servlet、Oracleの環境でDBロックの取得が出来なかった時に一定時間、間をおいて再度ロック取得を行いたいのですが、非スレッドでsleepメソッドのようなメソッド、クラスはありませんか? 教えて下さい。よろしくお願いします。

  • スレッドでの画面表示中に、マウス処理が重くなる

    画面クラス(class mytailf extends JFrame)と、ファイル読み込みクラス(class LogFilter extends Thread)があります。どちらも自作のクラスです。 ログファイルを読み込んで、画面に表示しているのですが、画面でのマウス操作が非常に重くなる場合があります。 質問1 画面クラス.ログ表示命令はどちらのスレッドで実行されるのでしょうか?ソースでは以下の部分です。 //ログを表示します。 myScreen.displayLog(strLine); 質問2 なにか改善策がありますでしょうか? なお、動作概要は以下のとおりです。 1.画面クラスを新規作成 2.画面クラスで、ファイル読み込みクラスを作成(引数は画面クラス)、Start()を実行 3.ファイル読み込みクラスで、ファイルから一行読み込み、画面クラス.ログ表示命令(引数は読み込んだ行)を呼び出す //-------------以下ソースの抜粋--------- // //画面制御系 // public class mytailf extends JFrame {   //ログの読み込みクラス   LogFilter  myLogFilter =  new   LogFilter( this );   //条件に応じて、ログを振り分けます   void  displayLog(String  strLine){     //ログを表示しているMDI子供窓に、ログを表示する処理   }   //   public static void main(String[] args) {     new mytailf("MyTail_F").setVisible(true);   } } // //ファイル読み込み系 // public class LogFilter  extends Thread{   //ログ読み込み処理本体   public   void  run(){     while  (ファイル読み込み中)  {       try {         //* ファイルから一行読み込みます。         //* ファイルから行が読み込めている間、以下の処理を繰り返します。         while (ファイルから行が読み込めている間) {           //ログを表示します。           myScreen.displayLog(strLine);           //~他のスレッドに実行権を渡そう~//           Thread.yield();           mySleepMs(100);           lineCnt++;           if(lineCnt >= 30){              mySleep(intWaitSec);             lineCnt =  0;           }         }       } catch (IOException e) {         showStatus("ファイルの読み込みに失敗しました。");         System.out.println(e);         return;       }       mySleep(intWaitSec);         }   }   //コンストラクタ   public   LogFilter(mytailf argScreen){     super();          myScreen  =  argScreen;        }   //ログファイルを開く   public void  openLogFile(String strFileName){     //略   }      //指定秒数待機   private void  mySleep(int argSleepSec){     mySleepMs(argSleepSec  *  1000); // X秒間停止   }   //ミリ秒待機   private void  mySleepMs(int  argSleepSec){     try {       Thread.sleep(argSleepSec); // Xミリ秒間停止     } catch (InterruptedException e) {       System.out.println(e);     }   } }

  • 310-035の参考書の中にあるThreadとRunnableの説明

    310-035の試験を1か月程勉強中です。スレッドについて頭がゴチャゴチャになってしまいました。 スレッドのインスタンス化ですが、 Threadを継承した場合は単純に Thread t = new Thread() でよいが、 Runnableを実装した場合は、 1行目// MyRunnable r = new MyRunnable(); 2行目// Thread t = new Thread(r) とする。とあります。 説明として、「Runnableの場合はスレッド自身のrun()メソッドではなく独自に定義したrun()メソッドを使用するようにするため」とあるのですが、何をいわんとしてるのか、この説明の意味がわからないのです。。 「スレッド自身のrun()メソッド」「独自に定義したrun()メソッド」って何のことを指してるんでしょうか。 「Threadを継承した場合」はオーバーライドしているので「スレッド自身のrun()メソッド」を見てるってことでしょうか。?? それと、どうしてRunnableの場合は、Threadをextendしてないのに急に2行目のところでThread が現われるんでしょうか。 アドバイスを頂けると助かります。宜しくお願いします。

    • ベストアンサー
    • Java