ここから本文です

インターフェースの実装でスレッドの中身を書くのと、スレッドを継承しただけのク...

dor********さん

2019/3/1110:01:10

インターフェースの実装でスレッドの中身を書くのと、スレッドを継承しただけのクラスを継承して具体的な動作を書くのは何が違うのですか?

継承も一つずつ積み重ねて機能を追加するのは出来るのですから、インターフェースを利用するメリットが良く分かりません。

閲覧数:
65
回答数:
5

違反報告

ベストアンサーに選ばれた回答

プロフィール画像

カテゴリマスター

ikt********さん

2019/3/1709:24:24

すでにご回答多数ですけれど。

確かに Javaは多重継承不可 だから... っていうのは
あるけど、そんな話抜きにしても、私なら
class MyClass extends Thread でやろうとは、
最初から思いません。
・本来やりたいこのと中味

・それをどこのスレッドでどう動かしたいか
とは、分けておきたいから。
#extends Thread 方式でいくと、上記2つの話が
#いっしょくたに混在した1枚クラスになります。

いっしょくたにすると、たとえば以下で困ります。
Thread#start は 1回こっきり なはずなので、
やりたいことを複数回スレッド実行にまたがって
進行したい場合、1インスタンスで素直に完遂できない。
毎回 new MyClass して start しないといけない。
継続保持したいコンテキストは、外で持たないといけなくなる。
本来やりたいことは、ふつうに MyClass の
個々インスタンスメソッドとして書き、
それらを 生成スレッドから呼び出して進行 すれば、
素直に状態継続できます。


というか、アプリケーション層で class Thread を
直接使うなんてこと、現在ではほとんど皆無なん
じゃないかと思う。
https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/E...
を初めとして、非同期並行処理をサービスしてくれる
ものは、多数あるからです。
これらはたいてい、
・Runnable オブジェクトを渡してくれればいいよ
になっている。
スレッドを用意する と利用者が本来やりたいこと の分離です。

質問本旨からははずれるけど、Java8から ラムダ がサポート
されたので、implements Runnable な何者かを作ってnew
する必要も、見かけ上不要になりました。

import java.util.concurrent.*;

class Hello {
    void sayHello() {
        System.out.println(Thread.currentThread() + ": Hello");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {;}
        System.out.println(Thread.currentThread() + ": Bye");
    }

    public static void main(String[] args) throws Exception {
        System.out.println(Thread.currentThread() + ": start");
        final var es = Executors.newFixedThreadPool(2);
        var me = new Hello();
        es.submit(me::sayHello);
        es.submit(me::sayHello);
        es.submit(me::sayHello);
        es.shutdown();
        es.awaitTermination(5, TimeUnit.SECONDS);
        System.out.println(Thread.currentThread() + ": end");
    }
}

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜4件/4件中

並び替え:回答日時の
新しい順
|古い順

a_s********さん

2019/3/1615:58:56

Runnableの場合は、下記のように複数スレッドで同じ変数にアクセスできます。
Thread継承のときはできません、別オブジェクトになります。

class ImplementsRunnable implements Runnable {

private int counter = 0;

public void run() {
counter++;
System.out.println("ImplementsRunnable : Counter : " + counter);
}
}


public class threadtest1
{
public static void main(String args[]) throws Exception {
// 複数スレッドで同じオブジェクト、変数にアクセスする場合
ImplementsRunnable rc = new ImplementsRunnable();
Thread t1 = new Thread(rc);
t1.start();
Thread.sleep(1000);
Thread t2 = new Thread(rc);
t2.start();
Thread.sleep(1000);
Thread t3 = new Thread(rc);
t3.start();
}
}
実行結果
C:\>c:\jdk11\bin\javac threadtest1.java
C:\>c:\jdk11\bin\java -cp . threadtest1
ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3

kon********さん

2019/3/1613:07:42

(new Thread(new Runnable(){
public void run(){System.out.println(0);}}){
public void run(){System.out.println(1);}}).
start();
実行させると1が表示されます。(少し古いですが
jdk9で確認)
Threadクラスの設計方針とか仕様で決まっている
のではないかと。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

ama********さん

2019/3/1600:56:51

例えばフレーム(JFrame)を継承したMyJFrameアプリケーションがあってとして、(Javaは多重継承ができないので)そのMyJFrameはThreadを継承することができません。
その場合にRunnableインターフェイスを使います。

ちなみに知らない間にThreadが非推奨に?(正式な非推奨では無いかもしれないが、そんなクズみたいなモノを何時までも使わないでくれよ、って話)

マルチコア時代のCPUリソースを有効活用--Java EE 7で進化した並列処理を理解する
https://builder.japan.zdnet.com/java/35032957/
https://builder.japan.zdnet.com/java/35032957/2/

プロフィール画像

カテゴリマスター

ii3********さん

2019/3/1110:19:46

Javaは多重継承ができないから。

例えば、SupuerClassAクラスを継承したSubClassBクラスがあり、
・SubClassBクラスにマルチスレッド機能を追加する。
・ただし、SupuerClassAクラスはシングルスレッドのままとする。
みたいな場合。

こういう時はRunnableインタフェースを実装するしかない。
だって、SubClassBクラスは既にSupuerClassAクラスを継承していて、Threadクラスを継承できないから。

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる