推奨されます, 2024

エディターズチョイス

Javaにおけるスレッドクラスと実行可能インタフェースの違い

スレッドは2つの方法で定義できます。 まず、すでにRunnableインターフェースを実装しているThreadクラス拡張します。 次に、 Runnableインターフェースを直接実装することです。 Threadクラスを拡張してスレッドを定義するときは、Threadクラスのrun()メソッドをオーバーライドする必要があります。 Runnableインターフェースを実装するスレッドを定義するときは、Runnableインターフェースの唯一のrun()メソッドを実装する必要があります。 ThreadとRunnableの基本的な違いは、Threadクラスを拡張することによって定義された各スレッドが一意のオブジェクトを作成し、そのオブジェクトに関連付けられることです。 一方、Runnableインタフェースを実装することによって定義された各スレッドは、同じオブジェクトを共有します。

以下に示す比較チャートを使用して、ThreadとRunnableの他のいくつかの違いを見てみましょう。

比較表

比較基準ランナブル
基本各スレッドは固有のオブジェクトを作成し、それに関連付けられます。複数のスレッドが同じオブジェクトを共有します。
記憶各スレッドが固有のオブジェクトを作成すると、より多くのメモリーが必要になります。複数のスレッドが同じオブジェクトを共有するので、使用されるメモリが少なくなります。
拡張Javaでは、多重継承は許可されていないため、あるクラスがThreadクラスを継承した後は、他のクラスを継承することはできません。クラスがRunnableインターフェースを実装するスレッドを定義する場合、それは1つのクラスを拡張する可能性があります。
つかいますスレッドクラス内の他のメソッドをオーバーライドする場合にのみ、ユーザーはスレッドクラスを拡張する必要があります。runメソッドを専門にしたいだけなら、Runnableを実装するのがより良い選択肢です。
カップリングThreadクラスのコードとそのスレッドに割り当てられたジョブも含まれるため、Threadクラスを拡張すると密結合が発生します。Runnableインターフェースを実装すると、ThreadのコードはThreadsのジョブとは別のものになるため、疎結合が発生します。

スレッドクラスの定義

Threadjava.langパッケージのクラスです。 ThreadクラスはObjectクラスを拡張し、 Runnableインタフェースを実装します。 Threadクラスには、スレッドを作成して操作するためのコンストラクタとメソッドがあります。 複数のスレッドを作成すると、各スレッドは固有のオブジェクトを作成し、そのオブジェクトに関連付けられます。 Threadクラスを拡張するスレッドを作成した場合、さらにjavaは多重継承をサポートしないため、他のクラスを拡張することはできません。 そのため、Threadクラスの他のメソッドもオーバーライドする場合にのみ、Threadクラスを拡張することを選択する必要があります。 Threadクラスを拡張するスレッドを作成する例を見てみましょう。

 / *スレッドの定義* /クラスMythreadはスレッドを拡張します{/ *スレッドのジョブ* / public void run(){(int i = 0; i <10; i ++){System.Out.Println( "Child Thread") ; mainThread {/ *メインスレッドのジョブ* / public static void main(String args []){Mythread mt = new Mythread();}} / *メインスレッドが子スレッドを作成しました* / mt.start(); for(int i = 0; i <10; i ++){System.Out.Print( "Main Thread"); メインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッド 

上記のコードでは、Threadクラスを拡張し、ThreadクラスのrunメソッドをオーバーライドするMythreadクラスを作成します。 mainメソッドを含むクラスで、Mythreadクラスのスレッドオブジェクト(mt)を作成し、そのスレッドオブジェクトを使ってstart()メソッドを呼び出しました。 startメソッドはスレッドの実行を開始し、同時にJVMはスレッドのrunメソッドを呼び出します。 現在、プログラムには2つのスレッドがあります。1つはメインスレッドで、もう1つはメインスレッドによって作成された子スレッドです。 両方のスレッドの実行は同時に発生しますが、正確な出力を装うことはできません。

Runnableインタフェースの定義

Runnablejava.langパッケージのインタフェースです。 Runnableインターフェースを実装することで、スレッドを定義できます。 Runnableインタフェースには単一のメソッドrun()があり、これはRunnableインタフェースを実装するクラスによって実装されています。 Runnableインターフェースを実装するスレッドを定義することを選択した場合でも、他のクラスを拡張することを選択できます。 Runnableインターフェースを実装して複数のスレッドを作成すると、各スレッドは同じ実行可能インスタンスを共有します。 Runnableインターフェースを使ってスレッドを定義する方法を学びましょう。

 / *スレッドの定義* /クラスRunnablethreadは、Runnableを実装しています{/ *スレッドのジョブ* / public void run(){(int i = 0; i <10; i ++){System.Out.Println( "Child Thread") ; mainThread {/ *メインスレッドのジョブ* / public static void main(String args []){Mythread rt = new Mythread();}} / *メインスレッドが実行可能オブジェクトを作成しました* / Thread t = new Thread(rt); / *メインスレッドは子スレッドを作成し、実行可能オブジェクトを渡します* / t.start(); for(int i = 0; i <10; i ++){System.Out.Print( "Main Thread"); メインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッドメインスレッド 

上記のコードでは、Runnableインターフェースを実装し、Runnableインターフェースのrun()メソッドを実装することによってスレッドのジョブを定義するクラスRunnablethreadを作成しました。 それから、mainメソッドを含むクラスmainthreadを作成します。 mainメソッド内で、Runnablethreadクラスの実行可能オブジェクトを宣言し、スレッドを宣言しながらこのオブジェクトをThreadのコンストラクタに渡しました。 このようにして、スレッドオブジェクト(t)と実行可能オブジェクト(rt)をリンクしました。 それから、スレッドオブジェクトはスレッドのstartメソッドを呼び出し、スレッドはさらにRunnablethreadクラスのrunメソッドを呼び出します。 実行可能オブジェクトをThreadオブジェクトにリンクしていなかった場合、スレッドのstartメソッドはThreadクラスのrunメソッドを呼び出したはずです。 さて、このコードにも2つのスレッドがあります。メインスレッドとメインスレッドは子スレッドを作成し、両方とも同時に実行されますが、正確な出力は見せかけられません。

Javaにおけるスレッドと実行可能ファイルの主な違い

  1. Threadクラスを拡張することによって作成された各スレッドは、それに対する固有のオブジェクトを作成し、そのオブジェクトに関連付けられます。 一方、Runnableインターフェースを実装することによって作成された各スレッドは、同じrunnableインスタンスを共有します。
  2. Threadクラスを拡張して作成すると、各スレッドは一意のオブジェクトに関連付けられるため、より多くのメモリが必要になります。 一方、Runnableインタフェースを実装することによって作成された各スレッドは同じオブジェクト空間を共有するため、必要なメモリが少なくて済みます。
  3. Threadクラスをさらに拡張すると、Javaでは多重継承が許可されないため、他のクラスを継承できますが、Runnableを実装すると、クラスが他のクラスを継承する可能性が残ります。
  4. Threadクラスの他のメソッドをオーバーライドまたは特殊化する必要がある場合にのみ、Threadクラスを拡張する必要があります。 runメソッドのみを特殊化したい場合は、Runnableインターフェースを実装する必要があります。
  5. Threadのコードとthreadのジョブは同じクラスに含まれるため、Threadクラスを拡張するとコード内で密接に結合されます。 一方、Runnableインタフェースを実装すると、Threadのコードはスレッドに割り当てられたジョブとは別のものになるため、コード内で疎結合が発生します。

結論:

Threadクラスを拡張するのではなく、Runnableインターフェースを実装することをお勧めします。 Runnableを実装すると、スレッドのコードがスレッドにジョブを割り当てるクラスとは異なるため、コードが疎結合になります。 メモリが少なくて済み、クラスが他のクラスを継承することもできます。

Top