1。スレッドの概念:スレッドは、最初から最後までタスクの実行フローを指します。スレッドは、タスクを実行するメカニズムを提供します。 Javaの場合、プログラムで複数のスレッドを同時に実行でき、これらのスレッドはマルチプロセッサシステムで同時に実行できます。プログラムがアプリケーションとして実行されると、JavaインタープリターはMain()メソッドのスレッドを起動します。
2。並列と並行性:
(1)並行性:単一のプロセッサシステムでは、複数のスレッドがCPU時間を共有し、オペレーティングシステムはリソースのスケジューリングと割り当てを担当します。
(2)並列性:マルチプロセッサシステムでは、複数のプロセッサが同時に複数のスレッドを実行できます。これらのスレッドは同時に同時に実行できます。並行性とは異なり、複数のスレッドのみがCPU時間を共有でき、1つのスレッドのみが同時に実行できます。
3。スレッドの作成:
(1)基本概念:Javaの各タスクは実行可能なオブジェクトです。タスクを作成するには、タスククラスを最初に定義する必要があり、タスククラスは実行可能なインターフェイスを実装する必要があります。スレッドは、基本的にタスクの実行に便利なオブジェクトです。スレッドの実行プロセスは、最後までタスククラスでrun()メソッドの実行です。
(2)実行可能なインターフェイスを介してスレッドを作成します。
a。実行可能なインターフェイスを実装するタスククラスを定義し、実行可能なインターフェイスにrun()メソッドを実装し(run()メソッドはシステムスレッドに実行方法を指示します)、run()メソッドで特定のタスクコードまたは処理ロジックを定義します。
b。タスククラスを定義した後、タスククラスのタスクオブジェクトを作成します。
c。タスクはスレッドで実行され、トレッドクラスのオブジェクトを作成し、実行可能なインターフェイスをパラメーターとしてトレッドクラスのコンストラクターに実装するタスククラスオブジェクトを渡す必要があります。
d。トレッドクラスオブジェクトのstart()メソッドを呼び出して、スレッドを開始します。タスクの実行()メソッドが実行されます。 run()メソッドが実行されると、スレッドが終了します。
例コード:
パッケージcom.muzeet.mutithread; //各タスクは実行可能なインターフェイスのインスタンスです。タスクは実行可能なオブジェクトであり、スレッドはタスクの実行を容易にするオブジェクトです。タスククラスを作成し、実行メソッドをオーバーライドしてタスクを定義する必要がありますパブリッククラスThreadDemo1実装{private int countdown = 10; @Override //実行方法を書き直して、タスクpublic void run(){countdown-> 0){system.out.println( "$" + thread.currentthread()。getName() + "(" + countdown + ")"); }} // STARTメソッドの呼び出しはスレッドを開始し、タスクの実行メソッドが呼び出されます。実行メソッドが実行された後、スレッドはpublic static void main(string [] args){runnable demo1 = new StreadDemo1()を終了します。スレッドスレッド1 =新しいスレッド(demo1);スレッドスレッド2 =新しいスレッド(demo1); thread1.start(); thread2.start(); System.out.println( "Rocket Launch CountDown:"); }}プログラムの実行結果:
ロケットローンチカウントダウン:$スレッド0(9)$スレッド0(8)$スレッド0(7)$ $ $ $ -0(6)$スレッド0(5)$スレッド-0(4)$スレッド-0(3)$スレッド-0(2)スレッド-0(1)$スレッド-0(0)
2つのタスクオブジェクトを同時に実行します。
public static void main(string [] args){runnable demo1 = new StreadDemo1(); runnable demo2 = new StreadDemo1();スレッドスレッド1 =新しいスレッド(demo1);スレッドスレッド2 =新しいスレッド(demo2); thread1.start(); thread2.start(); System.out.println( "Rocket Launch CountDown:"); }実行結果:
ロケットの打ち上げカウントダウン: $ STHREAD-0(9)$ STHREAD-0(8)$ THREAD-0(7)$ STHREAD-0(6)$ STHREAD-1(9)$ THREAD-0(5)$ STHREAD-1(8)$ STHREAD-0(4)$ STHREAD-1(7)$ STHREAD-0(3) $スレッド1(6)$スレッド1(5)$スレッド-0(2)$スレッド1(4)$ $ 1(3)$スレッド1(2)$スレッド1(1)$スレッド1(0)$スレッド-0(1)$スレッド-0(0)
(3)スレッドクラスを継承してスレッドを作成します。
a。最初にタスククラスを作成すると、スレッドクラスが拡張されます。スレッドクラスは実行可能なインターフェイスを実装するため、カスタマイズされたタスククラスは、特定のタスクコードまたは処理ロジックを定義する実行可能なインターフェイスとRerun()メソッドも実装します。
b。タスククラスオブジェクトを作成します。このオブジェクトは、スレッドを使用したり、カスタム変数タイプとして実行可能です。
c。カスタムオブジェクトのstart()メソッドを呼び出し、スレッドを開始します。
サンプルコード:
パッケージcom.muzeet.mutithread; //各タスクは実行可能なインターフェイスのインスタンスです。タスクは実行可能なオブジェクトであり、スレッドはオブジェクトを実行できます。タスククラスを作成する必要があり、実行方法をオーバーライドする必要がありますパブリッククラスの拡張機能を定義する必要があります。 @Override //実行方法を書き換えて、タスクpublic void run(){countdown-> 0){system.out.println( "$" + this.getName() + "(" + countdown + ")"); }} // STARTメソッドの呼び出しはスレッドを開始し、タスクの実行メソッドが呼び出されます。実行メソッドが実行された後、スレッドはpublic static void main(string [] args){extendfromthread thread1 = new extendfromthread()を終了します。 extendfromthread thread2 = new ExtendfromThread(); thread1.start(); thread2.start(); System.out.println( "Rocket Launch CountDown:"); }}実行結果:
ロケットの打ち上げカウントダウン: $ STHREAD-0(9)$ STHREAD-0(8)$ THREAD-0(7)$ STHREAD-0(6)$ THREAD-0(5)$ STHREAD-0(4)$ THREAD-0(3)$ THREAD-0(2)$ THREAD-0(1)$ Thread-0(0) $スレッド1(9)$スレッド1(8)$スレッド1(7)$スレッド1(6)$スレッド1(5)$スレッド1(4)$スレッド1(3)$スレッド1(2)$スレッド1(1)$スレッド1(0)
1つのスレッドは、実行する前に別のスレッドが終了するのを待ちます:printNumタスクを実行すると、番号50を印刷すると、文字cの印刷タスクを実行するようになり、スレッド4が実行された後も印刷されたタスクを実行し続けます。
パッケージcom.muzeet.testthread; public class printnum runnable {private int lastnum; public printnum(int n){lastnum = n; } @Override public void run(){// todo auto-eneratedメソッドスタブスレッド4 = new Thread(new Printchar( 'c'、40)); thread4.start(); try {for(int i = 1; i <= lastnum; i ++){system.out.println( ""+i); if(i == 50){thread4.join(); }}} catch(arturnedexception e){// dodo auto-enerated catch block e.printstacktrace(); }}}4。2つの方法の比較(転載)
まず、2つの方法の出力結果を分析します。また、2つのスレッドを作成します。なぜ結果が違うのですか?
実行可能なインターフェイスを使用してスレッドを作成すると、同じターゲットオブジェクト(treaddemo1tt = newTreadDemo1();)を共有し、同じリソースを処理するために複数の同一のスレッドを実装できます。最初のスレッドがタスクを完了すると、カウントダウンはすでに0であるため、2番目のスレッドは出力されません。スレッドでスレッドを作成する方法を継承すると、2つのタスククラスオブジェクトが作成され、それぞれのメンバー変数が作成され、互いに干渉しません。
次に、JDKからの説明を見てください。
実行可能なインターフェイスは、特定のスレッドを介してインスタンスを実行する予定のクラスで実装する必要があります。クラスは、実行と呼ばれるパラメーターレスメソッドを定義する必要があります。
このインターフェイスを設計する目的は、アクティブなときにコードを実行したいオブジェクトにパブリックプロトコルを提供することです。たとえば、スレッドクラスは実行可能です。アクティベーションとは、スレッドが開始されており、まだ停止していないことを意味します。
さらに、Runnableは、スレッドのサブクラスではないクラスのアクティベーション方法を提供します。スレッドインスタンスをインスタンス化し、実行中のターゲットとして自分自身を取得することにより、実行可能を実装するクラスを実行できます。ほとんどの場合、run()メソッドをオーバーライドし、他のスレッドメソッドをオーバーライドしない場合は、実行可能なインターフェイスを使用する必要があります。これは、プログラマーがクラスの基本的な動作を変更または強化する予定でない限り、そのクラスにサブクラスを作成しないでください。 (スレッドクラスを継承する代わりに、タスククラスの作成と実行可能なインターフェイスを実装することをお勧めします)
スレッドクラスの継承を採用してください:
(1)利点:簡単に書く。現在のスレッドにアクセスする必要がある場合は、thread.currentthread()メソッドを使用する必要はありません。これを使用して現在のスレッドを直接入手できます。
(2)短所:スレッドクラスがスレッドクラスを継承しているため、他の親クラスを継承することはできません。
実行可能なインターフェイスメソッドの使用:
(1)利点:スレッドクラスは実行可能なインターフェイスのみを実装し、他のクラスを継承することもできます。このようにして、複数のスレッドが同じターゲットオブジェクトを共有できるため、複数の同一のスレッドが同じリソースを処理するのに非常に適しているため、CPUコードとデータを分離して明確なモデルを形成できます。これは、オブジェクト指向のアイデアをよりよく反映します。
(2)短所:プログラミングは少し複雑です。現在のスレッドにアクセスする必要がある場合は、thread.currentthread()メソッドを使用する必要があります。
要約します
上記は、Javaマルチスレッドと比較コードの例でスレッドを作成する2つの方法についてのすべてです。私はそれが誰にでも役立つことを願っています。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!