この記事は、シアトルコンサルティング株式会社 Advent Calendar 2021の1日目の記事です。
こんにちは、シアトルコンサルティングの長岡と申します。
この度、弊社シアトルコンサルティング株式会社でAdvent Calendarに参加することになりました。
TeamTech Move the WorldをMissionに掲げ、日々全力で業務に取り組んでおります!
少しでも興味を持って頂けたら下記のサイトを覗いてみてください!
コーポレートサイト
https://www.seattleconsulting.co.jp/
Wantedly
https://www.wantedly.com/companies/seattleconsulting
よろしくお願い致します!
はじめに
今回はJavaにおけるマルチスレッドの実装例を紹介します。
実務でシングルスレッドからマルチスレッドへの改修案件に携わったこともあり、振り返りついでに紹介します。
前編は基本的な実装例、後編では実装の注意点について実装例を交えて紹介します。
エンジニアになって初めて担当させて頂いた案件で、駆け出しエンジニアの方たちにも理解できる内容だと思うので、ぜひ読んでみてください!
マルチスレッドとは
Javaが採用している並行処理プログラミングのモデルが「マルチスレッド」と呼ばれています。
本来プログラムは上から下に順に処理していきますが、マルチスレッドを実装すると本来順番に呼ばれるプログラムを同時に動作させることができます。
マルチスレッドのメリット
マルチスレッドを使用することにより、直列で処理していたプログラムを並列に処理していくため直列処理の待ち時間が無くなり、アプリケーション全体で見た実行速度が速くなります。
実装の注意点
各スレッドで同じオブジェクトにアクセスした際に、同じフィールドの値を変更してしまう為、期待した値にならない可能性があり注意が必要です。
実装例
マルチスレッドの実装には、RunnableかCallableを使用します。
Runnableの場合は戻り値の指定ができず、例外をスローできません。
Callableの場合は任意の戻り値を指定でき、例外をスローすることができます。
実務で使用したCallableを使用し、メインクラスから3つのサブクラスを並行して呼び出します。
サブクラスは、サブクラス名+開始 を表示した後、3秒間スリープし、サブクラス名+終了を表示させるプログラムにします。
package main;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) throws InterruptedException {
// 引数に生成するスレッド数を渡す
ExecutorService exec = Executors.newFixedThreadPool(3);
Callable<String> sub1 = new Sub1();
Callable<String> sub2 = new Sub2();
Callable<String> sub3 = new Sub3();
List<Callable<String>> tasklist = new ArrayList<>();
tasklist.add(sub1);
tasklist.add(sub2);
tasklist.add(sub3);
List<Future<String>> future = exec.invokeAll(tasklist);
}
}
サブクラスの3つは処理内容は同じで出力するサブクラス名が違うだけなので他二つは割愛します
package main;
import java.util.concurrent.Callable;
public class Sub1 implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("sub1開始");
Thread.sleep(3000);
System.out.println("sub1終了");
return null;
}
}
実行してみます。
sub1開始
sub3開始
sub2開始
sub3終了
sub2終了
sub1終了
成功です。
マルチスレッドで実行している為、実行する度に開始と終了の順番がバラバラになります。
さいごに
今回はプログラムをマルチスレッドで動かしてみました。
次回は実装する上での注意点、排他制御について書いていこうと思います。
Javaのマルチスレッド実装例(後編)