前書き: 今日のインターネット業界では、マルチスレッド テクノロジが非常に重要なスキルになっています。コンピュータ ハードウェアの発展に伴い、マルチスレッドによるプログラムのパフォーマンスの向上を期待して、マルチスレッド テクノロジに注目するプログラマーがますます増えています。広く使用されているプログラミング言語として、Java は豊富なマルチスレッド サポートも提供します。この記事では、読者が Java マルチスレッド テクノロジをより深く理解し、習得できるように、Java マルチスレッドの基本概念、原則、実装方法、および日常生活におけるアプリケーションを詳細に紹介します。
マルチスレッドの概要
キッチンで料理をしていて、2 つの異なる料理を同時に炒める必要があるとします。このシナリオでは、自分自身を 1 つのスレッドとして考えることができ、これら 2 つの皿は他の 2 つのスレッドを表します。
最初の野菜を炒めるときは、まず野菜を切り、鍋に油を熱し、それから野菜を鍋に加えて炒めます。各ステップを順番に実行する必要があるため、これは典型的なシリアル プロセスです。ただし、2 番目の料理を揚げるとき、この方法で行う場合は、1 番目の料理がすべての手順を完了するまで待ってから、2 番目の料理を開始する必要があります。これは明らかに非効率です。
この場合、マルチスレッドを使用すると効率が向上します。 1品目を炒めている間に2品目の材料をあらかじめ準備しておくこともできます。 1品目がまだ鍋で炒めている間に、野菜を切ったり、油を熱したりするなど、2品目の処理を始めることができます。こうすることで、時間を大幅に節約できます。
同じ原理がプログラミングにも当てはまります。シングルスレッドの場合、プログラムに複数のタスクが含まれている場合は、1 つのタスクが完了するまで待ってから次のタスクを開始する必要があります。マルチスレッドの場合、異なるタスクを異なるスレッドに割り当てて、同時に実行できるようにします。これにより、プログラムの効率が大幅に向上します。
スレッドの作成
1. Thread クラスを継承し、run() メソッドをオーバーライドします。
まずThreadクラスを継承し、run()メソッドをオーバーライドするクラスを作成し、runメソッド内にこのスレッドで実行するコードを記述します。
class thread extends Thread{
@Override
public void run(){
//thread.currentThread().getName()得到当前线程的名字
System.out.println("线程启"+thread.currentThread().getName()+"动了");
}
}
次に、オブジェクトを作成し、start メソッドを呼び出してスレッドを開始します。
public static void main(String[] args) {
thread thread = new thread();
thread.start();
}
演算結果
Runnable インターフェイスを実装し、run() メソッドを実装します。
まず、Runnable インターフェイスを実装するクラスを作成し、次に run() メソッドを実装します。
class thread1 implements Runnable{
public void run(){
System.out.println("线程启"+thread.currentThread().getName()+"动了");
}
}
別の Thread オブジェクトを作成し、Runnable インターフェイスを実装したオブジェクトをパラメータとして渡します。また、start メソッドを通じてスレッドを開始します
Thread thread1 = new Thread(new thread1());
thread1.start();
注 どちらのメソッドでも、run メソッドを介して直接スレッドを開始しないでください。これは、run メソッドを直接呼び出すと、同じスレッド上でタスクのみが実行され、スレッドが作成されないためです。新しいスレッド; 実際には、start メソッドが呼び出されるとき、最初にスレッドが作成され、次に run メソッドが実行されます。
比較する
2 番目の方法を使用することをお勧めします。料理の例を考えてみましょう。今、2 つの料理を作りたいとします。1 つは炒め物、もう 1 つはピザです。最初の方法を使用する場合、Thread を継承するクラスを 2 つ作成する必要があります。
public class Main {
public static void main(String[] args) {
CookFriedRice cookFriedRice = new CookFriedRice();
CookPizza cookPizza = new CookPizza();
cookFriedRice.start();
cookPizza.start();
}
}
class CookFriedRice extends Thread{
@Override
public void run(){
System.out.println("开始炒菜了!!!");
}
}
class CookPizza extends Thread{
@Override
public void run(){
System.out.println("开始做披萨了!!!");
}
}
Runnable インターフェイスを実装してスレッドを作成する場合、Runnable インターフェイスを実装するクラスを 2 つ定義するだけで済みます。クラスも 2 つ作成する必要はないのでしょうか? ? ?ラムダ式はここで使用できます (馴染みのない友人もこの記事を読むことができますラムダ式)
public class Main {
public static void main(String[] args) {
new Thread(()-> System.out.println("开始炒菜了!!!")).start();
new Thread(()-> System.out.println("开始做披萨了!!!")).start();
}
}
コードははるかに単純で、異なるスレッドが同じオブジェクトを操作して情報共有を実現できますか?
public class Main {
public static void main(String[] args) {
test test = new test();
Thread thread1 = new Thread(test);
Thread thread2 = new Thread(test);
thread1.start();
thread2.start();
}
}
class test implements Runnable {
private int count = 0;
public void run() {
count++;
System.out.println(count);
}
}
3. スレッドのステータス
スレッドのステータスとライフ サイクル
Java のスレッドには 6 つの状態 (新規、実行可能、実行中、ブロック済み)、待機中、終了があります。スレッドのライフサイクルには、新規、準備完了、実行中、ブロック、待機、終了の各段階が含まれます。
理解を助けるために料理の例を使用してみましょう:
キッチンでは、シェフが料理を準備しており、各シェフは独立したタスクのようなものです プロセッサ (別名)糸)。彼らは皆、独自のタスクのリストを持っており、独自の順序でそれらに取り組んでいます。
シェフのライフ ステータスは次の段階に分類できます。
新しいステータス (新規): シェフが採用され、対応するキッチン エリアに割り当てられて作業します。
準備完了状態 (実行可能): シェフは作業を開始する準備ができており、シェフがタスクを割り当てるのを待っています。
ブロック中: 調理器具が片づけられるのを待っている間など、シェフは他のシェフによって一時的にブロックされています。
実行状態 (Running): シェフが料理の準備を開始します。
終了: シェフは仕事を終えてキッチンを去りました。
詳細 例を参照 このメソッドは、スレッドをブロックして、子スレッドが終了するまで待機できます。 2. 参加 スレッドの実行中、実行の機会は次のとおりです。あきらめました。他のスレッド (コミュニティ) に渡しますが、その礼儀は成功しない可能性があります。CPU に実行権を与え、CPU が再スケジュールできるようにするだけです。 1.yield (静的メソッド) 以下にいくつかのメソッドを示します。
実際、スレッド呼び出しの開始後、プログラムは、割り当てられたシステムに応じて、遠くまで移動する場合と移動しない場合があります。このスレッド時間 (Java 仕様では、移動は別個の状態とみなされず、実行中のスレッドも移動状態になる可能性があります)。システムは各スレッドにタイム スライスを割り当てます。タイム スライスが使い果たされると、 CPU は次のスレッドに実行の機会を与えますが、この処理は非常に高速であるため、切り替え処理が検出できず、これらのスレッドが同時に実行されているように見えます。ビデオとフレーム単位の写真を比較できます。 :
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(()-> {
for (int i = 0; i < 100; i++) {
System.out.println(i+": 子线程在运行!!!");
}
});
thread1.start();
for (int i = 0; i <100 ; i++) {
System.out.println(i+": 主线程在运行!!!");
}
}
実行結果
サブスレッドとメインスレッドが同時に実行される
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(()-> {
for (int i = 0; i < 100; i++) {
System.out.println(i+": 子线程在运行!!!");
}
});
thread1.start();
for (int i = 0; i <100 ; i++) {
if(i%2==0)
thread1.join();
System.out.println(i+": 主线程在运行!!!");
}
}
}
結合を追加した後、メインスレッドは子スレッドが完了するのを待ってから実行されます。
この号はここまでです。文章が良いと思われる場合は、次の号に注目してください。
次号のプレビュー:
- スレッドの同期と相互排他
- スレッド間の通信
- スレッドプールの使用
- Java マルチスレッドの生活への応用