この記事では、マルチスレッドのJava並行処理関連の知識を導入し始めた開始し、関心と継続的な支援をありがとうございました。私はより多くのJava関連の知識を習得するために公共の「サイドJavaコード」の数が心配です。
スレッドを作成する方法
Javaでは、通常の方法ユーザーがスレッドを作成するためのイニシアチブを取る、3があり、すなわち、Threadクラスの継承、Runnableを実装し、呼び出し可能で
Threadクラスの継承
- クラス定義されたサブクラスを通し、クラスのrunメソッドをオーバーライドします。
- スレッドを開始するスレッドオブジェクトのstart()メソッドを呼び出します。
Threadクラススレッドが達成継承することによって、複数のスレッドのスレッドクラスのインスタンス変数(異なるスレッドオブジェクトを作成する必要があります)との間で共有することはできません。
/**
* 通过继承Thread实现线程
*/
public class MyThread extends Thread {
public void run() {
System.out.println("MyThread.run()");
}
}
MyThread myThread = new MyThread();
myThread.start();
Runnableを実装します
- あなたのクラスがすでに別のクラスを拡張する場合、それは直接スレッドを拡張することができない、この時間は、あなたは、Runnableインタフェースを実現することができます。
- スレッドを開始するスレッドオブジェクトのstart()メソッドを呼び出します。
/**
* 通过实现Runnable接口实现的线程类
*/
public class RunnableTest implements Runnable {
@Override
public void run() {
System.out.println("RunnableTest.run()");
}
public static void main(String[] args) {
RunnableTest runnableTest = new RunnableTest() ;
Thread thread = new Thread(runnableTest);
thread.start();
}
}
呼び出し可能な、未来のことで
スレッドとのRunnableは、2つの方法で見ることができ、いずれかの方法では、戻り値をサポートしていない、と例外がスローされ宣言することはできません。
これは、呼び出し可能な2つのインターフェイスが達成される戻り値を許容しながら、呼び出し可能などのインターフェースは、実行可能なスレッドとして()メソッドの呼び出しを提供するRunableインタフェースをアップグレード。
呼び出し可能なオブジェクトではなく、直接ターゲットThreadオブジェクトとして、我々は、コールのFutureTask呼び出し可能オブジェクト()メソッドの値を返しますをカプセル化するオブジェクトパッケージ呼び出し可能FutureTaskクラスのオブジェクトを、使用することができます。
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class CallableTest {
public static void main(String[] args) {
CallableTest callableTest = new CallableTest() ;
//因为Callable接口是函数式接口,可以使用Lambda表达式
FutureTask<String> task = new FutureTask<Integer>((Callable<String>)()->{
System.out.println("FutureTask and Callable");
return "hello word";
});
try{
System.out.println("子线程返回值 : " + task.get());
} catch (Exception e){
e.printStackTrace();
}
}
}
終了の方法をスレッド
スレッドの正常終了に加えて、3つの一般的な方法があり、スレッドがスレッドの終了を特定の方法を終了することができる:誘導灯出口スレッドを使用して、スレッドの**割り込み方法端部は、 STOP方法**は、スレッドを終了します。
誘導灯の終了スレッドを使用します
その実装の最も一般的に使用される方法は、以下のとおりです。このフラグに応じてスレッドrun()メソッドでブールフラグの種類の定義が終了するには、この作業は、通常(ランに配置されているかどうかを決定するために真であるか偽であります)whileループ処理を行います。
public class ThreadSafe extends Thread {
public volatile boolean exit = false;
public void run() {
while (!exit){
//do work
}
}
public static void main(String[] args) throws Exception {
ThreadFlag thread = new ThreadFlag();
thread.start();
sleep(5000); // 主线程延迟5秒
thread.exit = true; // 终止线程thread
thread.join();
System.out.println("线程退出!");
}
}
スレッドを終了する割り込み方法
スレッドを中断するために()メソッドを使用し、割り込み、2つのケースがあります。
- スレッドがブロックされています。中古SLEEP、同期ロック待ち、受信機のソケットとして、スレッドがブロックされるようになります、のように受け入れます。
使用 interrupt 方法结束线程的时候,一定要先捕获 InterruptedException 异常之后通过 break 来跳出循环,才能正常结束 run 方法。
public class ThreadInterrupt extends Thread {
public void run() {
try {
sleep(50000); // 延迟50秒
}
catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) throws Exception {
Thread thread = new ThreadInterrupt();
thread.start();
System.out.println("在50秒之内按任意键中断线程!");
System.in.read();
thread.interrupt();
thread.join();
System.out.println("线程已经退出!");
}
}
- どのスレッドがブロックされていません。使用isInterruptedを()割り込みフラグ判定スレッドは、ループを終了します。割り込み()メソッドを使用する場合、割り込みフラグがtrueに設定され、サイクルを制御するために使用する自己定義されたフラグは、同じ理由です。
public class ThreadSafe extends Thread {
public void run() {
while (!isInterrupted()) { //非阻塞过程中通过判断中断标志来退出
try {
Thread.sleep(5*1000);//阻塞过程捕获中断异常来退出
} catch (InterruptedException e) {
e.printStackTrace();
break;//捕获到异常之后,执行 break 跳出循环
}
}
}
}
stopメソッドは、スレッドを停止します
Stopメソッドは、実行中のスレッドを終了または中断を余儀なくされる可能性があります。私たちは、スレッドを終了するには、次のコードを使用することができます。
thread.stop();
ストップを使用して安全でない次のように、メイン衝突点:
- Thread.stopの後に()子スレッドのスレッドを作成するための呼び出しがThreadDeatherrorエラーがスローされます。
- ストップ子スレッドへの呼び出しが開催されたすべてのロックを解放します。(制御不能)すべてのロックの突然のリリースが保持しているスレッドを引き起こし、保護されたデータの不整合をレンダリングすることが可能です。
概要
- スレッドの作成:継承に比べて、Runnableをを使用してスレッドまたは呼び出し可能な方法を作成し、推奨、インタフェースの実装はJavaの単一継承に限定されるものではなく、より柔軟にすることができます。
- スレッドの終了:割り込みフラグを推奨または終了スレッドを終了、停止スレッド・セーフな方法、簡単に一貫性のないデータにつながります。