マルチスレッドの使用には多くのことが含まれるため、2 つの記事に記録されます。
目次
プロセスとスレッド
1 はじめに
プログラムはコンピューター命令の集合であり、プロセスは実行中のプログラムであり、コードのロード、実行から完了までの完全なプロセスを指します。各プロセスは異なるメモリ空間を占有します。
スレッドはプロセス内の単一の連続した制御フローであり、軽量プロセスとも呼ばれ、オペレーティング システムによってスケジュールされ、プロセッサまたはカーネル上で実行されます。プロセスにはメイン スレッドがあり、プロセスは複数のスレッドで構成することもできます。各スレッドは異なるタスクを並行して実行します。これらの複数のスレッドはメモリ空間を共有します。
2. マルチスレッドの利点
(1) マルチスレッド技術によりプログラムの応答が高速化
(2) 現在処理中のタスクが存在しない場合、CPU の処理時間を他のタスクに割り当てることができます。
(3) 多くの CPU 処理時間を必要とするタスクは、定期的に他のタスクに処理時間を放棄する可能性があります。
(4) いつでもタスクを停止できます
(5) タスクの優先度を設定することで、タスクに優先順位を付けることができます
3. マルチスレッドを実装する 2 つの方法
どちらの方法も例としてチケットの販売を使用します
(1)、スレッドを継承
メリット:書きやすい。現在のスレッドにアクセスする必要がある場合は、Thread.currentThread() メソッドを使用する必要はなく、これを使用することで直接現在のスレッドを取得できます。
欠点: スレッド クラスは Thread クラスを継承しているため、他の親クラスを継承できません。
具体的な手順:
1. Thread サブクラスを作成します。
2. Thread クラスのメソッドをオーバーライドします。
3. Thread サブクラス オブジェクト、つまりスレッド オブジェクトを作成します。
4. スレッド オブジェクトの start() メソッドを呼び出してスレッドを開始すると、システムは書き換えられた run() メソッド内の特定の実装を自動的に呼び出します。
コード例:
package Study;
public class Exp03 extends Thread{
int ticket=6;
//重写Thread类的run()方法
public void run(){
//持续卖票。一直到剩余票数为0
while(this.ticket>=0){
System.out.println(this.getName()+"卖票-->"+(this.ticket--));
//对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
}
}
public static void main(String[] args){
Exp03 thread1=new Exp03();
Exp03 thread2=new Exp03();
thread1.setName("窗口1");
thread2.setName("窗口2");
thread1.start(); //线程运行
thread2.start();
}
}
出力結果
この例では、2 つのスレッドが作成されて許可されているため、複数の実行の出力結果は異なる場合があることに注意してください。スレッドはスレッド スケジューリングを通じて実行されるため、多くのスレッドが準備完了状態を処理しますが、実際に実行されているスレッドは 1 つだけです。したがって、オペレーティング システムは、アイドル状態のスレッドを削除し、他のスレッドに実行させます (スレッド スケジューリング)。
プログラムが呼び出された順序でスレッドを実行する必要がある場合は、実行前に前のスレッドが終了したかどうかを確認する必要があります。これは、次のブログ投稿で説明するスレッド同期で説明されます。
(2) Runnableインターフェースの実装
利点: スレッド クラスは Runnable インターフェイスのみを実装し、他のクラスも継承できます。複数のスレッドは同じターゲット オブジェクトを共有できます。これは、複数の同一のスレッドが同じリソースを処理している状況に非常に適しています。
欠点: 現在のスレッドを取得するには、Thread.currentThread() メソッドを使用する必要があります。
具体的な手順
1. Runnable インターフェイスを実装し、run() メソッドを実装するクラスを定義します。
2. Thread クラスのターゲット パラメータとして Runnable オブジェクトを作成し、Thread オブジェクト (実際のスレッド オブジェクト) を作成します。
3. start() メソッドを呼び出してスレッドを開始します。
コード例 (2 つの例。例 2 では、この方法の利点を利用して例 1 を変更します):
例 1:
package Study;
public class Exp03 implements Runnable{
int ticket=6;
//重写Thread类的run()方法
public void run(){
//持续卖票。一直到剩余票数为0
while(this.ticket>=0){
System.out.println(Thread.currentThread().getName()+"卖票-->"+(this.ticket--));
//对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
}
}
public static void main(String[] args){
Exp03 t1=new Exp03(); //创建线程类对象
Exp03 t2=new Exp03();
Thread thread1=new Thread(t1); //创建线程
Thread thread2=new Thread(t2);
thread1.setName("窗口1"); //给线程命名
thread2.setName("窗口2");
thread1.start(); //线程运行
thread2.start();
}
}
出力結果
Runnable を利用して、複数のスレッドが同じリソースを処理できるようにインスタンス 1 を変更します。
例 2:
package Study;
public class Exp03 implements Runnable{
int ticket=6;
//重写Thread类的run()方法
public void run(){
//持续卖票。一直到剩余票数为0
while(this.ticket>=0){
System.out.println(Thread.currentThread().getName()+"卖票-->"+(this.ticket--));
//对于设置线程名称,Thread类自带getName方法和setName方法。也可以使用构造方法进行设置
}
}
public static void main(String[] args){
Exp03 t1=new Exp03(); //创建线程类对象
Thread thread1=new Thread(t1); //创建线程
Thread thread2=new Thread(t1);
thread1.setName("窗口1"); //给线程命名
thread2.setName("窗口2");
thread1.start(); //线程运行
thread2.start();
}
}
出力結果:
出力結果から、2 つのウィンドウがオブジェクト t1 の 6 枚のチケットを同時に販売していることがわかります。したがって、2 つのウィンドウは、インスタンス 1 の 12 枚のチケットではなく、合計 6 枚のチケットを販売します。
したがって、マルチスレッドを使用して共有リソースを処理する場合は、Runnable インターフェイス メソッドを使用するのが非常に適しています。