- ベストアンサー
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 が現われるんでしょうか。 アドバイスを頂けると助かります。宜しくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>java.lang.ThreadのインスタンスというのはだいたいThreadを拡張(extends Thread)しないとできないんじゃないか・・と思い混乱しています。 そんなことはありません。 extendsしていないjava.lang.Threadのインスタンスは取得できます。 >Runnableの実装の場合について、(以下略) >これってどうしてなんでしょうか。 逆に聞くと、何で素のjava.lang.Threadのインスタンスが作れないんですか? と言うことになります。 落ち着いて考えてください。 runの中身を「Threadの子クラス」に書くか、「Runnableを実装したクラス」に書くか、です。 Threadをextendsするのは「Threadの子クラス」を使うやり方だけです。 「Runnableを実装したクラス」を使う場合はThreadには手をつけません。 --------------------------- 2つのやり方があるのです。 ●Threadの子クラスを使う Threadを継承、run()をオーバーライドするのは、Threadの子クラスのインスタンス単独でスレッドを走らせるときのみです。 このときは実行する処理を「Threadの子クラスのrun()」に書きます。 public myThread extends java.lang.Thread { public void run() { /*別スレッドでやらせたい処理*/ } } myThread th = new myThread(); th.start(); ●Runnableを実装したクラスを使う 素のThreadクラスとRunnableインターフェイスを実装したクラスのインスタンスをでスレッドを走らせるときは、Threadの継承、run()をオーバーライドする必要はありません。 このときは実行する処理を「Runnableインターフェイスを実装したクラスのrun()」に書きます。 public anyRunnable Implements java.lang.Runnable { public void run() { /*別スレッドでやらせたい処理*/ } } anyRunnable anyRun = new anyRunnable (); Thread th = new Thread(anyRun); th.start(); Threadの継承は必須ではありません。
その他の回答 (3)
- ngsvx
- ベストアンサー率49% (157/315)
単純な話です。 Threadオブジェクトは、コンストラクタにRunnableオブジェクトが指定されたときは、そのRunnableオブジェクトのrunメソッドを実行し、 コンストラクタに何も渡されなければ自分の(Threadオブジェクトの)runメソッド(オーバーライドされたものを含む)を実行する。 ということです。
お礼
ご回答ありがとうございました。なるほど・・コンストラクタに何も渡されなければThreadオブジェクトのrunメソッドをみてるんですね。 ありがとうございました。
- bnosuke-x
- ベストアンサー率39% (43/110)
スレッドを実行するときには「駆動するもの」と「駆動されるもの」の2つが必要です。 「車」と「荷物」のようなものです。 荷物を運ぶときは、 1)車の荷台に直接載せる方法と、 2)荷物を別の「荷台だけの車(トレーラー)」に載せて、車に牽かせる方法があります。 1)の方法は、荷物を車の荷台に載せて自分だけで走ります。 ですが、この車は走ることが目的のものなので、あまり荷物は載せたくないのが正直なところです。 2)の方法は、荷物をトレーラーに載せて、車とつなげて運びます。 トレーラーは荷物を載せるのが目的のものなので、存分に荷物を載せられます。 ポイントは、「どちらにしても車は必要」だと言うことです。 上の車と荷物の話をJavaのスレッドの話に置き換えると下のようになります。 車:Threadクラス 荷物:runメソッドの中身 荷台:runメソッド 荷台だけの車(トレーラー):Runnableインターフェイスを実装したクラス 荷物を載せる:runメソッドの中身を書く トレーラーと車をつなげる:Runnableインターフェイスを実装したクラスのインスタンスに、Threadクラスのインスタンスを割り当てる そして、 車の荷台に載せる方法:Threadのrunメソッドをオーバーライドする方法 トレーラーに乗せてそれを牽く方法:Runnableインターフェイスを実装したクラスのrunメソッドを使う方法 です。 どちらの方法でも「runメソッドをThreadクラスのインスタンスが駆動してゆく」という点では変わりません。 その証拠にThreadクラス自身もRunnableインターフェイスを実装しています。 以上をふまえて、ご質問にお答えします。 >「スレッド自身のrun()メソッド」 Threadクラスを継承して作ったクラスのrunメソッド >「独自に定義したrun()メソッド」 Runnableインターフェイスを実装したクラスのrunメソッド です。 >それと、どうしてRunnableの場合は、Threadをextendしてないのに急に2行目のところでThread が現われるんでしょうか。 Runnableインターフェイスを使う場合にThreadクラスが登場するのは、Runnableインターフェイスを実装したクラスのrunメソッドをThreadクラスのインスタンスが呼び出して処理が進むからです。 ところで、sunのドキュメントを読むと、 「Thread クラスのメソッドのうち、run() だけをオーバーライドして使用する場合は、Runnable インタフェースを使用してください。これは、クラスの基本的な動作を修正または拡張するのでない限り、そのクラスをサブクラス化することは好ましくないため、重要です。」 とあります。 Threadを継承するときはThreadの亜種を作る場合にするのが望ましく、スレッドで別処理をさせたいだけなら、そのためのクラスを別に作りましょう、と言うことだと思います。 たいていの書籍は、インターフェイスの説明が必要ないので、Threadの継承で説明が始まっていると思いますが、クラスの設計上はあまりよくないと思うので、小さいものでもRunnableインターフェイスを使ったやり方の方がいいと思います。
お礼
ご回答ありがとうございます。 しくみ等納得できました。分りやすいご説明ありがとうございました。 ここでまた分らない点があります。 Runnableの実装にしてもjava.lang.Threadの拡張(extends Thread)にしてもjava.lang.Threadのインスタンスというのを呼び出そうとしています。 java.lang.ThreadのインスタンスというのはだいたいThreadを拡張(extends Thread)しないとできないんじゃないか・・と思い混乱しています。 Runnableの実装の場合について、Threadを拡張(extends Thread)してないのに、急にThread t = new Thread(r) というかんじでjava.lang.Threadのインスタンスを明示的に取得できてますよね…。 これってどうしてなんでしょうか。 ご回答に対する御質問となってしまいすみません。 もしお時間があれば宜しくお願いします。
- PED02744
- ベストアンサー率40% (157/390)
単一継承とインタフェースの話だと思われます。 Javaは多重継承を許さないので、こんなことになってます。 詳細は、ここを http://msugai.fc2web.com/java/thread/create.html
お礼
ご回答ありがとうございます。参考urlありがとうございました。 Javaは多重継承を許さない。。たしかにそうでした。 ありがとうございました。
お礼
ご回答ありがとうございました。 extendsしていないjava.lang.Threadのインスタンスは取得できます。・・ という部分でようやく理解できるようになりました。 これまで分ったような分らないようなというかんじで暗記的に進めていましたが、これでスレッドの部分がスッキリしました。本当にお世話になりました、ありがとうございました。