Javaのマルチスレッドシリーズの第5章。
スレッドとは何ですか
プログラムのどのスレッドがどのようにのようなものではありません想像してみて?Baiduのネットワークディスクのファイルをアップロードするとき、アップロードを提出するために待たなければならないが完了したファイルをダウンロードし、ファイルをダウンロードしません。プログラムは、スレッドクレジットされている複数の機能を同時に実行することが可能に私たちは慣れているので、これは我々は今、人類に対して見えます。
前の記事には、プロセス知っ複数のプログラムの並列実行、という概念を導入するプロセスを実現するためには、言及を。今すぐスレッドの導入は、プログラムを同時に実行できるようにすることです。
スレッドで構成
スレッドID:スレッド識別子。
現在の命令ポインタ(PC) :小数点命令が実行されます。
レジスタ設定:ユニットを格納するレジスタのセットを。
スタック:データとアドレスのブレークポイントを一時的に格納すると、一般的にサイトを保護するために使用。
スレッドとプロセスとの間の差
スレッドとプロセスの違いは、私たちは、両者の差が、プロセスは家で家の中で人々のスレッドを住んでいた3人、が住んで家を表示するには、この例を使用することができると思います。プロセスは、独自のリソースを持つ独立したエンティティであり、スレッドは、複数のスレッドがプロセスのリソースを共有するプロセスです。
スレッド状態
私たちは、列挙スレッドの状態は以下の6つを持って、Javaソースコード内で参照してください。
public enum State {
//新建状态
NEW,
//运行状态
RUNNABLE,
//阻塞状态
BLOCKED,
//等待状态
WAITING,
//等待状态(区别在于这个有等待的时间)
TIMED_WAITING,
//终止状态
TERMINATED;
}
以下の6つの状態11の次に説明することができません。
NEW:新しい状態。あなたがスレッドではなく、実行開始を()を作成する前に、スレッドは、NEW状態となっています。この時点で、スレッド、ちょうどオブジェクトとは、実際のマップが存在しないと言うことができます。
RUNNABLE:実行されています。スレッドオブジェクトのスタートを()を呼び出した後、JVMの本当のスレッドが存在することを示して実行可能状態に入りました。
BLOCKED:ブロッキング状態。スレッドは、モニターロックの取得を待機しているロックの解除を待ちます。
WAITING:待ち状態。この状態のスレッドがCPUを割り当てられません場合は、ディスプレイやウェイクアップする必要があり、それ以外の場合は永遠に待機します。
TIMED_WAITING:タイムアウト待ち状態。この状態の同じスレッドがCPUを割り当てられませんが、それは無期限に待機しません、時間制限があり、時間は待って停止しています。
TERMINATED:終了ステータス。スレッドの実行の終了が完了しているが、これは、オブジェクトが、オブジェクトがまだ存在していないことを意味するものではありませんが、スレッドが存在しません。
非常に多くのスレッドの状態があるので、それはステートマシンを持っている必要があり、それは、状態B状態になるどのような状況の下で、です。ここでの簡単な説明です。
私たちは、新しいスレッドのクラスを持っている場合、次の図に関連して、つまりNEW
呼び出し、開始()入力するように、メソッドをRUNNABLE
トリガーが待っていれば、その後、その後、入力し、状態をWAITING
トリガ待ちのタイムアウトが、その後、入力した場合は、状態をTIMED_WAITING
必要がアクセスを同期する際に、状態をリソース、一つのスレッドだけが入るように、他のスレッドにアクセスすることができたときBLOCKED
の状態を、スレッドが実行されると、入力TERMINATED
状態に。
実際には、JVMのスレッドで以下に示すように、興味のある学生はそれを理解することができ、9つの州です。
javaClasses.hpp
enum ThreadStatus {
NEW = 0,
RUNNABLE = JVMTI_THREAD_STATE_ALIVE + // runnable / running
JVMTI_THREAD_STATE_RUNNABLE,
SLEEPING = JVMTI_THREAD_STATE_ALIVE + // Thread.sleep()
JVMTI_THREAD_STATE_WAITING +
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
JVMTI_THREAD_STATE_SLEEPING,
IN_OBJECT_WAIT = JVMTI_THREAD_STATE_ALIVE + // Object.wait()
JVMTI_THREAD_STATE_WAITING +
JVMTI_THREAD_STATE_WAITING_INDEFINITELY +
JVMTI_THREAD_STATE_IN_OBJECT_WAIT,
IN_OBJECT_WAIT_TIMED = JVMTI_THREAD_STATE_ALIVE + // Object.wait(long)
JVMTI_THREAD_STATE_WAITING +
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
JVMTI_THREAD_STATE_IN_OBJECT_WAIT,
PARKED = JVMTI_THREAD_STATE_ALIVE + // LockSupport.park()
JVMTI_THREAD_STATE_WAITING +
JVMTI_THREAD_STATE_WAITING_INDEFINITELY +
JVMTI_THREAD_STATE_PARKED,
PARKED_TIMED = JVMTI_THREAD_STATE_ALIVE + // LockSupport.park(long)
JVMTI_THREAD_STATE_WAITING +
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
JVMTI_THREAD_STATE_PARKED,
BLOCKED_ON_MONITOR_ENTER = JVMTI_THREAD_STATE_ALIVE + // (re-)entering a synchronization block
JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER,
TERMINATED = JVMTI_THREAD_STATE_TERMINATED
};
Javaスレッドの実装
ここでは、Javaでスレッドを作成する方法について話をします。我々はすべて、2つの方法でJavaスレッドの実装知っているように:継承ThreadクラスをしてRunnableを実装します。
Threadクラスの継承
継承Threadクラス、オーバーライドするrun()
方法を。
class MyThread extends Thread {
@Override
public void run() {
System.out.println("MyThread");
}
}
Runnableを実装
Runnableを実装し、実装するrun()
方法を。
class MyRunnable implements Runnable {
public void run() {
System.out.println("MyRunnable");
}
}
这 2 种线程的启动方式也不一样。MyThread
是一个线程类,所以可以直接 new
出一个对象出来,接着调用 start()
方法来启动线程;而 MyRunnable
只是一个普通的类,需要 new
出线程基类 Thread
对象,将 MyRunnable
对象传进去。
下面是启动线程的方式。
public class ThreadImpl {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread myRunnable = new Thread(new MyRunnable());
System.out.println("main Thread begin");
myThread.start();
myRunnable.start();
System.out.println("main Thread end");
}
}
打印结果如下:
main Thread begin
main Thread end
MyThread
MyRunnable
看这结果,不像咱们之前的串行执行依次打印,主线程不会等待子线程执行完。
敲重点:不能直接调用 run()
,直接调用 run()
不会创建线程,而是主线程直接执行 run()
的内容,相当于执行普通函数。这时就是串行执行的。看下面代码。
public class ThreadImpl {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread myRunnable = new Thread(new MyRunnable());
System.out.println("main Thread begin");
myThread.run();
myRunnable.run();
System.out.println("main Thread end");
}
}
打印结果:
main Thread begin
MyThread
MyRunnable
main Thread end
从结果看出只是串行的,但看不出没有线程,我们看下面例子来验证直接调用 run()
方法没有创建新的线程,使用 VisualVM 工具来观察线程情况。
我们对代码做一下修改,加上 Thread.sleep(1000000)
让它睡眠一段时间,这样方便用工具查看线程情况。
调用 run()
的代码:
public class ThreadImpl {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.setName("MyThread");
Thread myRunnable = new Thread(new MyRunnable());
myRunnable.setName("MyRunnable");
System.out.println("main Thread begin");
myThread.run();
myRunnable.run();
System.out.println("main Thread end");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("MyThread");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyRunnable implements Runnable {
public void run() {
System.out.println("MyRunnable");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
main Thread begin
MyThread
只打印出 2 句日志,观察线程时也只看到 main
线程,没有看到 MyThread
和 MyRunnable
线程,印证了上面咱们说的:直接调用 run()
方法,没有创建线程。
下面我们来看看有
调用 start()
的代码:
public class ThreadImpl {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.setName("MyThread");
Thread myRunnable = new Thread(new MyRunnable());
myRunnable.setName("MyRunnable");
System.out.println("main Thread begin");
myThread.start();
myRunnable.start();
System.out.println("main Thread end");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
main Thread begin
main Thread end
MyThread
MyRunnable
すべてのログがプリントアウトされ、そしてを通じてVisualVMのツール見ることができるMyThread
とMyRunnable
のスレッドを。この結果を見て、呼び出すためのスレッドを作成することを忘れないstart()
方法を。
まず、後者のコンテンツに注力していき、今日これについて話しました。
推荐阅读
シリアル、パラレルを学ぶことができるファーストフードを食べる、同時
背景返信「デザインモード」電子ブック「デザインパターンの物語」を得ることができます
觉得文章有用帮忙转发&点赞,多谢朋友们!