スレッドと並行スレッド
基本的な概念
プログラム:コンピュータが認識して実行できる一連の命令は、静的コードです。
プロセス:プログラムの実行中のアクティビティ、実行中のプログラム。
スレッド:プロセスのコンポーネントであり、実行の順次フローを表します。
スレッドの接触を処理します。
①スレッドはプロセスの最小実行および割り当て単位であり、独立して移動することはできず、プロセスに依存する必要があります。多数のスレッドがプロセスを構成しています。
②リソースがプロセスに割り当てられ、同じプロセスのすべてのスレッドがプロセスのすべてのリソースを共有します。
プロセススレッドの違い:
①スケジューリング:スレッドはスケジューリングと割り当ての基本単位であり、プロセスはリソースを所有する基本単位です
②同時実行性:プロセスを同時に実行できるだけでなく、同じプロセスの複数のスレッドを同時に実行することもできます。
③資源を所有する:プロセスは資源を所有する独立した単位であり、スレッドはシステム資源を所有しないが、プロセスに属する資源にアクセスすることができる
④システムのオーバーヘッド:プロセスを作成またはキャンセルする場合、システムはリソースを割り当てて再利用する必要があるため、
システムのオーバーヘッドは、スレッドの作成または取り消しのオーバーヘッドよりも大幅に大きいため、マルチスレッドを使用するとリソースのオーバーヘッドを削減できます
ライフサイクル
-
新入生のステータス:
newキーワードとThreadクラスまたはそのサブクラスを使用してスレッドオブジェクトを作成すると、スレッドオブジェクトは新しい状態になります。プログラムがこのスレッドを開始()するまで、この状態のままです。
-
準備完了状態:
スレッドオブジェクトがstart()メソッドを呼び出すと、スレッドは準備完了状態になります。準備完了状態のスレッドは準備キューにあり、JVMのスレッドスケジューラによるスケジュールを待機しています。
-
稼働状況:
準備完了状態のスレッドがCPUリソースを取得すると、run()を実行でき、スレッドは実行状態になります。実行状態のスレッドは最も複雑で、ブロックされ、準備ができて、停止する可能性があります。
-
ブロッキング状態:
スレッドがsleep、suspendなどのメソッドを実行し、占有されているリソースを失うと、スレッドは実行状態からブロック状態になります。スリープ時間が経過した後、またはデバイスリソースを取得した後で、準備完了状態に再び入ることができます。3つのタイプに分けることができます:
-
ブロッキング待ち:実行状態のスレッドは、wait()メソッドを実行して、スレッドをブロッキング待ち状態に移行させます。
-
同期ブロッキング:スレッドは同期ロックの取得に失敗します(ロックが他のスレッドによって占有されているため)。
-
その他のブロッキング:スレッドのスリープ()または結合()を呼び出してI / O要求が発行されると、スレッドはブロッキング状態になります。
sleep()状態がタイムアウトになると、join()はスレッドの終了またはタイムアウトを待機するか、I / O処理が完了し、スレッドが再び準備状態に入ります。
-
-
死の状態:
実行状態のスレッドがタスクを完了するか、他の終了条件が発生すると、スレッドは終了状態に切り替わります。
スレッドを作成する方法
スレッドクラスを継承する
1.スレッドを継承するサブクラスを定義する
2.サブクラスはスレッドのrunメソッドをオーバーライドします
3.サブクラスオブジェクトをインスタンス化してスレッドを作成する
4. startメソッドを呼び出してスレッドを開始します
ソースコード
public class TestThread {
public static void main(String[] args) {
//创建线程方法1 继承Thread,重写run
NewThread thread = new NewThread();
thread.start();
System.out.println("主线程开始打印数据");
for (int i = 0; i < 5; i++) {
System.out.println("主线程:"+i);
}
}
}
class NewThread extends Thread{
@Override
public void run() {
System.out.println("分支线程开始打印数据");
for (int i = 0; i < 5; i++) {
System.out.println("分支线程:"+i);
}
}
}
プログラムを数回実行し、コンソールで取得した結果が異なることを確認します。これは、CPUスケジューリングのランダム性です。
Runnableインターフェースを実装する
1. Runnableインターフェースを実装するサブクラスを定義します
2.サブクラスはRunnableのrunメソッドを実装します
3. Threadクラスコンストラクターを介してスレッドオブジェクトを作成する
4. Runnableインスタンスを引数としてコンストラクタに渡します
5. Threadインスタンスのstartメソッドを呼び出してスレッドを開始します
ソースコード
public class TestThread {
public static void main(String[] args) {
//创建线程方法2 实现Runnable接口
Thread thread = new Thread(new NewRunnable());
thread.start();
System.out.println("主线程开始打印数据");
for (int i = 0; i < 5; i++) {
System.out.println("主线程:"+i);
}
}
}
class NewRunnable implements Runnable {
@Override
public void run() {
System.out.println("分支线程开始打印数据");
for (int i = 0; i < 5; i++) {
System.out.println("分支线程:"+i);
}
}
}
2つの作成方法の違い
- Runnableインターフェイスを実装して複数のスレッドを作成する場合、スレッドクラスはRunnableインターフェイスのみを実装し、他のクラスを継承することもできます。(推奨)
- 複数のスレッドが同じRunnable実装クラスオブジェクトを共有できるため、リソースの同期に役立ちます。
- Threadクラスを継承してマルチスレッドを作成するときに、現在のスレッドにアクセスする必要がある場合は、これを直接使用して現在のスレッドを取得します。
スレッドクラス
工法
一般的な方法
方法 | 機能説明 |
---|---|
public void start() | このスレッドは実行を開始し、Java仮想マシンはスレッドのrunメソッドを呼び出します。 |
public void run() | 独立したRunnable runオブジェクトを使用してスレッドが構築されている場合、Runnableオブジェクトのrunメソッドが呼び出され、それ以外の場合、メソッドは何もせずに戻ります。 |
public final void setName(String name) | スレッド名をパラメーター名と同じになるように変更します。 |
public final void setPriority(int priority) | スレッドの優先順位を変更します。 |
public final void setDaemon(boolean on) | スレッドをデーモンスレッドまたはユーザースレッドとしてマークします。 |
public final void join(long millisec) | このスレッドが終了するまで待機する最大時間は、ミリ秒ミリ秒です。 |
public void interrupt() | スレッドを中断します。stop()は廃止されました。 |
public final boolean isAlive() | スレッドがアクティブかどうかをテストします。 |
公開最終同期void結合(ミリ秒) | このスレッドの終了を待機する最大時間はミリ秒ミリ秒です |
public static void yield() | スレッドは、現在実行中のスレッドオブジェクトを生成、一時停止し、他のスレッドを実行します。 |
public static void sleep(longミリ秒) | 現在実行中のスレッドを、指定されたミリ秒以内にスリープ(実行を中断)します。 |
パブリック静的スレッドcurrentThread() | 現在実行中のスレッドオブジェクトへの参照を返します。 |
優先度
/** * The minimum priority that a thread can have. */
public final static int MIN_PRIORITY = 1;
/** * The default priority that is assigned to a thread. */
public final static int NORM_PRIORITY = 5;
/** * The maximum priority that a thread can have. */
public final static int MAX_PRIORITY = 10;
範囲は1〜10です。数値が大きいほど、システムコールの確率が高くなります。デフォルトの優先順位は5です。
テストコードの例
public class FunctionTest {
public static void main(String[] args) throws InterruptedException {
Thread threadChild = new NewThread();
Thread threadRun = new Thread(new NewRunnable(),"线程2 ");
//先设置优先级
threadChild.setPriority(1);
threadRun.setPriority(10);
//启动线程
threadChild.start();
threadRun.start();
//获取线程属性
threadChild.setName("线程1 ");
System.out.println(threadChild.getName());
System.out.println(threadRun.getName());
System.out.println(Thread.currentThread().getName());
if (threadChild.isAlive())
System.out.println(threadChild.getName()+"活着");
System.out.println("------有人在中间插队------");
threadChild.join();//执行完毕才到下一行
System.out.println("------有人在中间插队------");
//打印线程状态
threadRun.interrupt();
System.out.println(threadChild.isAlive());
System.out.println(threadRun.isAlive());
}
}
追記
上記は非常に基本的な概念の理解です。
次のような多くの問題が実際のアプリケーションで発生します。
- スレッド同期
- スレッド間通信
- スレッドのデッドロック
- スレッド制御:一時停止、停止、再開