Javaでマルチスレッドを作成する7つの方法
1. Threadクラスを継承する
1. コード例
public class Thread01 extends Thread {
// 线程执行的代码在run()方法中,执行完毕后,线程死亡
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "子线程执行完毕");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + "我是主线程");
//启动线程调用start()方法而不是run()方法 调用start()后线程变为就绪状态,而不是运行状态,还需等待CPU调度运行
new Thread01().start();
new Thread01().start();
System.out.println("---主线程执行完毕---");
}
}
実行結果は次のとおりです。
main我是主线程
---主线程执行完毕---
Thread-0<我是子线程>
Thread-1<我是子线程>
Thread-1子线程执行完毕
Thread-0子线程执行完毕
2. まとめ
メインスレッドは、次のプログラムを実行する前にサブスレッドの実行が完了するまで待つ必要がないことがわかります。メインスレッドの実行が完了した後も、サブスレッドはまだ実行中です。したがって、サブスレッドによって報告されるエラーは、 -thread はメインスレッドに影響を与えません。
2. 実行可能なインターフェースを実装する
1. コード例
public class Thread02 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
}
public static void main(String[] args) {
System.out.println("主程序运行");
new Thread(new Thread02()).start();
new Thread(new Thread02()).start();
System.out.println("主程序运行结束---");
}
}
操作結果:
主程序运行
主程序运行结束---
Thread-0<我是子线程>
Thread-1<我是子线程>
3. 匿名の内部クラスを使用する
public class Thread02 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
}
public static void main(String[] args) {
System.out.println("主程序运行");
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
}
}).start();
System.out.println("主程序运行结束---");
}
}
操作結果:
主程序运行
主程序运行结束---
Thread-0<我是子线程>
4. ラムダ式を使用する
public class Thread02 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
}
public static void main(String[] args) {
System.out.println("主程序运行");
new Thread(() -> System.out.println(Thread.currentThread().getName() + "<我是子线程>")).start();
System.out.println("主程序运行结束---");
}
}
操作結果:
主程序运行
主程序运行结束---
Thread-0<我是子线程>
5. callable と Future を使用して作成する
1 はじめに
Callable と future は、すぐに返された結果を取得できます。最下層は LockSupport に基づいています。Callable インターフェイスは、Runable の拡張バージョンである JDK5 から提供されています。
2. コードの実装
public class ThreadCallable implements Callable<Integer> {
/**
* 当前线程需要执行的代码,以及返回结果
* @return
* @throws Exception
*/
@Override
public Integer call() throws Exception {
System.out.println("子线程开始执行。。");
try {
Thread.sleep(3000);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+":返回1");
return 1;
}
}
public class Thread03 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadCallable threadCallable = new ThreadCallable();
FutureTask<Integer> futureTask = new FutureTask<>(threadCallable);
new Thread(futureTask).start();
Integer result = futureTask.get();
System.out.println(Thread.currentThread().getName()+","+result);
}
}
実行結果は次のとおりです。
子线程开始执行。。
Thread-0:返回1
main,1
3. 注意
futureTask はスレッドの結果を返すことができます。実際、get() メソッドが呼び出されると、基礎となる LockSupport が LockSupport.park() メソッドを呼び出し、メイン スレッドがハングアップして待機します。子スレッドの実行が終了した後、結果を返すと、LockSupport.unpark() メイン スレッドによって起動されます。子スレッドが結果を返す前に、メインスレッドはブロックされて待機します。
6. Executor Frameworkなどのスレッドプールを利用して作成する
public class Thread04 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> System.out.println("我是子线程"));
}
}
7. spring @Async 非同期アノテーション
呼び出されたメソッドに @Async アノテーションを記述するだけで、@Async アノテーションが付けられたメソッドは非同期で実行されます。これは、メイン スレッドで別のスレッドを開始して実行するのと同じです。