記事ソース:https://www.jianshu.com/p/ba24b782d5ca
記事対応するビデオソース:https://developer.aliyun.com/course/1012?spm=5176.10731542.0.0.6ef2d290hxQ4g0
マルチスレッド継承THEADクラスが実装
Javaのありjava.lang.Threadのそのようなクラスの長い連続がスレッドをオーバーライドする必要があるため、そこに私たちのクラスのメインスレッドが、このクラスは、マルチスレッド処理を達成することができることを意味しないことを示すことになるクラスのは、クラス提供ラン()メソッドが、この方法は、メインスレッドの方法に属します。
例:クラスのマルチスレッド本体
class MyThread extends Thread {//线程的主体类
private String title;
public MyThread(String title) {
this.title = title;
}
@Override
public void run() {//线程的主体方法
for (int i = 0; i < 10; i++) {
System.out.printf("%s运行.i = %s \n", this.title, i);
}
}
実行されるマルチスレッド機能は、run()メソッドで定義されるべきです。
あなたは、クラスを使用する場合は、通常の状況下では、ので、それはオブジェクトのインスタンスを生成しなければならないし、クラス内のメソッドが提供さ呼び出すことが、run()メソッドは直接呼び出されません:ことに留意すべきですそうしなければならないマルチスレッドを使用して開始するために、リソーススケジューリングの問題があったこのオペレーティングシステム起動は、()メソッドが完了しました。
例:マルチスタートスレッド
public class ThreadDemo {
public static void main(String[] args) {
new MyThread("线程A").start();
new MyThread("线程B").start();
new MyThread("线程C").start();
}
}
この時点でstart()メソッドの呼び出しが、最終的に()メソッドを実行しているんが、あなたは、見つけるために呼び出すことができ、すべてのオブジェクトは、実行の交互スレッドです。
質問:なぜマルチスレッドで直接実行起動しない()メソッドは何Threadクラスのstart()メソッドを使用する必要がありますか?あなたはこの問題をクリアしたい場合は、最善のアプローチは、start()メソッドを達成するための動作を見ている、それがソースコードを直接観察することができます。
public synchronized void start() {
if (threadStatus != 0) //判断线程的状态
throw new IllegalThreadStateException();//抛出一个异常
group.add(this);
boolean started = false;
try {
start0();//在start()方法中调用了start0()
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
private native void start0();//只定义了方法名称,但没有实现
例外はRuntimeExceptionが、唯一のオブジェクトの各スレッドクラスのサブクラスでなければならないため、開始()例外クラスのないIllegalThreadStateExceptionターゲットをスローします方法が、全体のプログラムとは、使用しないに明確にはtry..catchプロセスをスローしたりすることを発見反復スタートないIllegalThreadStateException例外は、例えば、スローされた場合、再起動を許可:次のコードは、例外をスローします。
public class ThreadDemo {
public static void main(String[] args) {
MyThread mt= new MyThread("线程A");
mt.start();
mt.start();//重复进行了线程的启动
}
}
Exception in thread "main" java.lang.IllegalThreadStateException
アカウントに開発者のための需要のさまざまなレベルを取ってJavaプログラムの実装の過程では、それは、ローカルのオペレーティングシステムの関数呼び出しをサポートしていますが、この技術は、JNI(Javaネイティブintefaceを)技術と呼ばれているが、Javaの開発プロセスこのような使用は推奨されないで、この技術の使用は、基礎となるオペレーティングシステム機能、一部特プロセスの一部を使用することができ、そしてこの方法は、異なるオペレーティングシステムの実装の必要性に依存して示している()START0スレッドクラスで提供します。
Threadクラスのstart()メソッド:いずれの場合では、限り、マルチスレッド、マルチスレッド開始の定義として、常に唯一のプログラムです。
マルチスレッドに基づいて実行可能なインターフェース
それは定義された継承Threadクラスを介してマルチスレッド達成することが可能であるが、継承するJavaプログラムにはいつも、Javaで、単一継承の制限が存在し、定義を提供しながら、第2のマルチスレッドの主構造を形成する:達成するJavaの.lang.Runnable以下のように定義されているインタフェース:
@FunctionalInterface //从JDK1.8引入Lambda表达式后就变为了函数式的接口
public interface Runnable{
public void run();
}
例:クラスのRunnableの本体を通ってマルチスレッド
class MyThread implements Runnable {//线程的主体类
private String title;
public MyThread(String title) {
this.title = title;
}
@Override
public void run() {//线程的主体方法
for (int i = 0; i < 10; i++) {
System.out.printf("%s运行.i = %s \n", this.title, i);
}
}
}
しかし、今ではスレッドの親クラスを継承することはありませんので、その後、MyThreadクラスのこの時のために、もはや支持体には、(スタート)メソッドはこれを継承していますが、起動しない場合は()メソッドは、その後、マルチスレッドのスタートではありません今回は提供Threadクラスのコンストラクタを見てする必要があります。
コンストラクタ:公共スレッド(Runnableをターゲット);
例:スタートマルチスレッド
public class ThreadDemo {
public static void main(String[] args) {
Thread threadA=new Thread(new MyThread("线程对象A"));
Thread threadB=new Thread(new MyThread("线程对象B"));
Thread threadC=new Thread(new MyThread("线程对象C"));
threadA.start();//启动多线程
threadB.start();//启动多线程
threadC.start();//启动多线程
}
}
この時間マルチスレッディングこの設計は、設計の標準タイプである、スレッドメインクラスは、もはや単一継承の限界を有しているので、この場合には、唯一の実装ので、Runnableをインタフェースオブジェクトを見つけることができません。
JDK1.8が最初から見つけることができる、のRunnableインタフェースは、機能インタフェース定義を使用していますので、直接、ラムダ式のスレッドクラスの実装を使用することができます。
例:マルチスレッドセットラムダの使用
public class ThreadDemo {
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
String title = "线程对象" + i;
// Runnable run = () -> {
// for (int j = 0; j < 10; j++) {
// System.out.printf("%s运行.j = %s \n", title, j);
// }
// };
// new Thread(run).start();
new Thread(() -> {
for (int j = 0; j < 10; j++) {
System.out.printf("%s运行.j = %s \n", title, j);
}
}).start();
}
}
}
マルチスレッドの場合、優先順位は、今後の開発に、Runnableインタフェースを実現し、Threadクラスを通じて、マルチスレッドを起動することです。
Runnableを持つスレッドの関係
それを回避することができるので、確かにRunnableを持つ最も便利であるThreadクラス、コード自体が懸念している場合は、Runnableインタフェース:分析の一連のを見つけることができた後、すでに実装プロセスの複数のスレッドに2つのアプローチを持っていました単一継承の制限は、同僚が良く、拡張機能することができます。
しかし、我々はまた、構造からスレッドとのRunnable接触を観察THEADの定義を開く必要があります。
public class Thread extends Object implements Runnable {}
スレッドクラスは、サブクラスが上書きまたは実行スレッドクラスの継承のRunnableインターフェース()場合、プログラムのクラス構造の場合を見ように、Runnableをインタフェース見出されます
class MyThread implements Runnable {//线程的主体类
private String title;
public MyThread(String title) {
this.title = title;
}
@Override
public void run() {//线程的主体方法
for (int i = 0; i < 10; i++) {
System.out.printf("%s运行.i = %s \n", this.title, i);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
Thread threadA=new Thread(new MyThread("线程对象A"));
Thread threadB=new Thread(new MyThread("线程对象B"));
Thread threadC=new Thread(new MyThread("线程对象C"));
threadA.start();//启动多线程
threadB.start();//启动多线程
threadC.start();//启动多线程
}
}
プロキシデザインパターンの構造、ユーザー定義のが、メインスレッドは、プロジェクトのコアを実装するための責任があり、そしてすべての補助は、すべてのThreadクラスによって扱わ達成を使用してマルチスレッドの設計、。
電話をかける際にマルチスレッドスレッドの開始は、start()メソッドで、そのrun()メソッドを見つけたが、Threadクラスのコンストラクタメソッドによって、Runnableインタフェースオブジェクトを渡され、そのオブジェクトは、Threadクラスのインタフェースになります開始()に格納されたターゲット属性は、メソッドを実行するスレッドのrun()メソッドを呼び出し、run()メソッドは、Runnableインタフェースサブクラスで被覆された書かれたrun()メソッドが呼び出されます。
マルチスレッドは、開発の本質は、複数のスレッドがメインスレッドスレッド、その後、同じリソースをつかむことができるということである本質的なことは記載されており、リソースの説明は、Runnableを介して行われます。
例:複数のスレッドによる同時アクセスを実現するためのリソースは、プログラムを発券利用します
class MyThread implements Runnable {//线程的主体类
private int ticket = 5;
@Override
public void run() {//线程的主体方法
for (int i = 0; i < 100; i++) {
if (this.ticket > 0)
System.out.printf("卖票,ticket = %s \n", this.ticket--);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
MyThread mt = new MyThread();
new Thread(mt).start();//第一个线程启动
new Thread(mt).start();//第二个线程启动
new Thread(mt).start();//第三个线程启动
}
}
この手順は、図を解析することにより、メモリの構造を分析するために行きました。
呼び出し可能マルチスレッド
最も伝統的な開発から、あなたはマルチスレッドのRunnableに頼ることを確認したい、しかしときのRunnable、戻り値の完全な実装を取得することができない新しいスレッドを実現JDK1.5から作られたので、Runnableインタフェースは、欠点を持っている場合インターフェース:java.util.concurrent.Callableのインタフェースは、最初にすべてのこの定義インタフェースを観察します:
@FunctionalInterface
public interface Callable<V>{
public V call() throws Exception;
}
あなたがジェネリックを設定することができたときに呼び出し可能な定義を見つけることができ、このジェネリック型は、データの戻り値の型であるので、ダウンキャストを回避するための利点は、セキュリティ上のリスクをもたらします。
例:呼び出し可能なマルチスレッド処理を用い
class MyThread implements Callable<String> {//线程的主体类
@Override
public String call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println("*********** 线程、i = " + i);
}
return "线程执行完毕。";
}
}
public class ThreadDemo {
public static void main(String[] args) throws Exception {
FutureTask<String> task = new FutureTask(new MyThread());
new Thread(task).start();
System.out.println("【线程返回数据】" + task.get());
}
}
状態を実行中のスレッド
マルチスレッドの発展のために、プログラミングのプロセスはに従って常にある:スレッドの主要なカテゴリの定義、およびその後、Threadクラスを通じてスレッドを開始するが、それはあなたがstart()メソッドを呼び出すことを意味するものではありませんが、スレッドがすでに実行を開始しました全体のプロセスは、状態を実行中のスレッドの独自のセットを持っているので。
図1に示すように、任意のオブジェクトThreadクラスのスレッドは、包装のために使用されるべきで、スレッドスタート(開始するために使用される)が、実際には、開始スレッドの数は、状態、レディ状態に設定され、現在は行われていない場合、
2 、スレッドスケジューリング動作状態(run()メソッド)に成功、しかし、すべてのスレッドまでは、いくつかの一時停止を持っている中央の必要性を下に実行できない場合、リソースのスケジューリングを待った後、レディ状態に入ります例えば:一定期間後にスレッドがこのスレッドがブロッキング状態に入り、その後、再び準備完了状態に戻ります、リソースを実行する必要があります。
3、run()メソッドが終了したときに、実際には、スレッドの主なタスクが終わったので、その後は停止状態に直接行くことができます。