Javaマルチスレッド面接トップ40問と回答 – 2026年版

Javaマルチスレッド面接の準備には、並行性概念の深い理解と実践経験が必要です。以下に、基本定義から仮想スレッドと構造化並行性などの高度なトピックまでをカバーする、厳選された40の質問と専門家の回答を掲載します。
👉 無料PDFダウンロード:Javaマルチスレッド面接質問と回答
1) Javaにおけるマルチスレッドとは何か、なぜ使用されるのか?
マルチスレッドにより、Javaアプリケーションは複数のスレッドを同時に実行でき、CPU利用率を最大化しレスポンシブネスを向上させます。特にI/Oバウンドタスク、大規模計算、一方のスレッドがブロックしても他方が処理を継続できるGUI更新で価値があります。
メリット
- CPU利用率の向上
- 独立操作のレイテンシ削減
- UIレスポンシブネスの向上
例:Webサーバーは各リクエストを別スレッドに割り当てることで、I/O操作でブロックすることなく数十のクライアントリクエストを同時に処理できます。
2) Javaにおけるスレッドのライフサイクルを説明してください。
Javaスレッドは以下の状態を経由します:
| 状態 | 説明 |
|---|---|
| New | スレッド作成済みだが未開始。 |
| Runnable | 実行準備完了または実行中。 |
| Blocked | モニタロックを待機中。 |
| Waiting | 他スレッドのシグナルを無期限待機。 |
| Timed Waiting | 指定時間待機。 |
| Terminated | 実行完了。 |
t.start()呼び出し時にスレッドはNewからRunnableへ移行します。
3) プロセスとスレッドの違いは?
| 基準 | プロセス | スレッド |
|---|---|---|
| メモリ | 独自アドレス空間 | プロセスメモリを共有 |
| 通信 | IPC必要 | メモリ直接共有 |
| 生成コスト | 高コスト | 軽量 |
| 障害影響 | 隔離 | 兄弟に影響の可能性 |
例:ブラウザプロセスはレンダリング、ネットワーク、ユーザーインタラクション用の複数スレッドを含む場合があります。
4) Javaでの同期はどう機能するか?
同期は共有リソースへのアクセスを一度に1スレッドのみに保証し、レースコンディションとデータ破損を防ぎます。synchronizedキーワードはメソッド全体または特定ブロックをロックします。
- 同期メソッド – メソッドのモニタをロック。
- 同期ブロック – 選択したオブジェクトをロック。
synchronized void increment() { count++; }
5) Javaでスレッドを作成するさまざまな方法は?
Threadを拡張class MyThread extends Thread { public void run() { System.out.println("Thread running"); } } new MyThread().start();Runnableを実装class MyRunnable implements Runnable { public void run() { System.out.println("Runnable running"); } } new Thread(new MyRunnable()).start();- Callable & Future(モダン) – 値を返し、チェック例外をスロー可能。
Callable
task = () -> 42; Future result = executor.submit(task); System.out.println(result.get());
6) start()とrun()の違いは?
| 側面 | start() | run() |
|---|---|---|
| スレッド生成 | 新OSスレッド作成 | 現在スレッドで実行 |
| 呼び出し | JVMでスレッドスケジュール | 単純メソッド呼び出し |
| 並行性 | 非同期実行 | 逐次実行 |
t.start()は新スレッドを起動;t.run()は他のメソッドと同様に振る舞います。
7) スレッドセーフティの概念と達成方法を説明してください。
スレッドセーフティは共有データへの並行アクセスが状態を破損しないことを保証。以下で達成可能:
synchronizedブロックまたはメソッドvolatile変数- 明示的ロック(例:
ReentrantLock、ReadWriteLock) - スレッドセーフコレクション(
ConcurrentHashMap、CopyOnWriteArrayList) - アトミッククラス(
AtomicInteger、AtomicBoolean)
AtomicInteger counter = new AtomicInteger(); counter.incrementAndGet();
8) wait()、sleep()、yield()の違いは?
| メソッド | クラス | ロック解放 | 目的 | 期間 |
|---|---|---|---|---|
wait() | Object | Yes | 通知待機 | 通知まで |
sleep() | Thread | No | 実行一時停止 | 固定時間 |
yield() | Thread | No | スケジューラ切替提案 | 予測不能 |
スレッド間通信にはwait()、スレッド一時停止にはsleep()を使用。
9) Executorフレームワークがスレッド管理をどう改善するか?
フレームワークはタスク送信とスレッド生成を分離し、効率的なスレッドプーリングとリソース再利用を可能にします。java.util.concurrentの一部で、以下を提供:
- スレッド再利用によるオーバーヘッド削減
- 柔軟なプールタイプ(Fixed、Cached、Single、Scheduled、Work-Stealing)
- グレースフルシャットダウン機構
ExecutorService executor = Executors.newFixedThreadPool(5); executor.submit(() -> System.out.println("Task executed")); executor.shutdown();
10) Javaで利用可能なスレッドプールの種類は?
| プールタイプ | ファクトリメソッド | 説明 |
|---|---|---|
| FixedThreadPool | newFixedThreadPool(n) | 固定スレッド数 |
| CachedThreadPool | newCachedThreadPool() | 必要に応じてスレッド生成、アイドル再利用 |
| SingleThreadExecutor | newSingleThreadExecutor() | 逐次実行用単一ワーカースレッド |
| ScheduledThreadPool | newScheduledThreadPool(n) | 遅延・周期的タスク対応 |
| WorkStealingPool | newWorkStealingPool() | 利用可能プロセッサーを動的活用 |
11) Javaにおけるデッドロックとは何か、どう防止するか?
デッドロックは2つ以上のスレッドが互いのロック解放を無限に待機する状態。通常は一貫性のないロック順序から生じます。
synchronized (A) { synchronized (B) { /*...*/ } }
synchronized (B) { synchronized (A) { /*...*/ } }
防止策:
- グローバルな一貫した順序でロック取得。
- タイムアウト付き
tryLock()使用。 - 可能な限りネストロック回避。
- 手動ロックより高レベル並行ユーティリティ優先。
12) synchronizedとReentrantLockの違い。
| 機能 | synchronized | ReentrantLock |
|---|---|---|
| 取得 | 暗黙的 | lock()で明示的 |
| 解放 | メソッド終了で自動 | unlock()で手動 |
| 試行/タイムアウト | 不可 | tryLock()とタイムアウト対応 |
| 公平性 | 設定不可 | 公平順序対応 |
| 条件変数 | 非対応 | 複数Conditionオブジェクト対応 |
ReentrantLock lock = new ReentrantLock(); if (lock.tryLock(1, TimeUnit.SECONDS)) { try { /* critical section */ } finally { lock.unlock(); } }
13) volatileとsynchronizedの違い。
| 側面 | volatile | synchronized |
|---|---|---|
| 目的 | 可視性 | 原子性 + 可視性 |
| 原子性 | 保証なし | 保証 |
| ロック | なし | あり |
| ユースケース | シンプルフラグ | 複合操作 |
volatile boolean running = true;
synchronized void increment() { count++; }
14) JavaのThreadLocalを説明してください。
ThreadLocalはスレッド固有データを提供し、共有ミュータブル状態の必要性を排除。各スレッドが独自の分離されたコピーにアクセスします。
ThreadLocalcounter = ThreadLocal.withInitial(() -> 0); counter.set(counter.get() + 1);
- データ破損防止
- スレッドごとのコンテキスト(セッションID等)に有用
- スレッドプールでは
remove()呼び出しでメモリリーク防止必須
15) Javaのアトミッククラスとは何か、なぜ使用されるか?
アトミッククラス(AtomicInteger、AtomicBoolean、AtomicReference等)はCAS(Compare-And-Swap)を用いてロックフリー・スレッドセーフ操作を実行。同期ブロック比でシンプルな更新に高スループットを提供。
AtomicInteger counter = new AtomicInteger(); counter.incrementAndGet();
16) セマフォとは何か、ロックとどう異なるか?
| 側面 | セマフォ | ロック |
|---|---|---|
| 目的 | 同時アクセス制限 | 相互排他 |
| 許可数 | 複数 | 単一 |
| ブロッキング | 許可取得 | 所有権取得 |
| ユースケース | 接続プーリング | クリティカルセクション保護 |
Semaphore sem = new Semaphore(3); sem.acquire(); // リソース使用 sem.release();
17) Fork/Joinフレームワークを説明してください。
Java 7で導入。ワークスティーリングアルゴリズムを用いて再帰的に分割可能なタスクの並列実行を可能に。アイドルスレッドがビジーなスレッドから作業を盗み、CPU利用率を最大化。
class SumTask extends RecursiveTask{ protected Integer compute() { if (end - start <= threshold) return computeDirectly(); int mid = (start + end) / 2; SumTask left = new SumTask(start, mid); SumTask right = new SumTask(mid, end); left.fork(); return right.compute() + left.join(); } }
18) CompletableFutureが非同期プログラミングをどう改善するか?
CompletableFutureはノンブロッキング、合成可能な非同期操作を可能にし、コールバック地獄を排除し、チェイニング、例外処理、並列合成をサポート。
CompletableFuture.supplyAsync(() -> "Hello") .thenApply(str -> str + " World") .thenAccept(System.out::println);
19) デーモンスレッドとは?
デーモンスレッドはバックグラウンドで実行し、ガベージコレクションやタイマータスクなどのサービスを提供。ユーザースレッドが残っていない場合、JVMはすべてのデーモンスレッドを自動的に終了させます。
Thread daemon = new Thread(() -> System.out.println("Daemon running")); daemon.setDaemon(true); daemon.start();
20) Javaマルチスレッドのベストプラクティス。
- 高レベル並行ユーティリティ(ExecutorService、BlockingQueue)を優先。
- 共有ミュータブル状態を避け、不変性を支持。
- 同期ラッパーより並行コレクション優先。
- 割り込みを正しく処理し、割り込みフラグを復元。
shutdown()またはshutdownNow()でエグゼキューターをグレースフルにシャットダウン。- 同期スコープを最小化し競合削減。
- 最適化前にプロファイリング;JFRやasync-profiler等ツールでホットスポット特定。
21) Javaメモリモデル(JMM)とは何か、なぜ重要か?
JMMはスレッドがメモリを通じてどう相互作用するかを定義し、可視性、順序性、原子性を保証。happens-before関係を確立し、正しい並行コード記述に不可欠。
- 可視性:一スレッドの変更が他スレッドから見えること。
- 順序性:一貫性維持のためアクションが順序付けられること。
- 原子性:特定操作が不可分であること。
22) ConcurrentHashMapとsynchronizedMapの違い。
| 機能 | ConcurrentHashMap | synchronizedMap |
|---|---|---|
| ロック粒度 | セグメントレベル(部分的) | マップ全体 |
| 競合時性能 | 高 | 低 |
| Nullキー/値 | 不可 | 可 |
| イテレータ一貫性 | 弱く一貫 | Fail-fast |
| 並行読み取り | 許可 | ブロック |
23) デッドロックの検出とデバッグ。
jstack <pid>によるスレッドダンプでデッドロック判明。- VisualVMやJConsoleでリアルタイムスレッド監視。
ThreadMXBean.findDeadlockedThreads()でプログラム的検出。
24) 並列ストリーム vs 明示的スレッド。
並列ストリームは内部でFork/Joinフレームワークを使用し、データ処理のハイレベルAPIを提供。明示的スレッドは手動管理が必要だが細かい制御が可能。
| 側面 | 並列ストリーム | スレッド |
|---|---|---|
| 抽象化 | ハイレベルAPI | ローレベル制御 |
| 管理 | ForkJoinPool経由で自動 | 手動スレッドプール |
| チューニング | コモンプール使用 | カスタムプールサイズ |
| エラー処理 | 限定的 | 完全制御 |
25) CountDownLatch、CyclicBarrier、Phaser。
| 機能 | CountDownLatch | CyclicBarrier | Phaser |
|---|---|---|---|
| リセット | 不可 | 可 | 可 |
| 当事者数 | 固定 | 固定 | 動的 |
| ユースケース | タスク完了待機 | スレッド合流 | 動的調整 |
CountDownLatch latch = new CountDownLatch(3); for (...) new Thread(() -> { /* work */ latch.countDown(); }).start(); latch.await();
26) CallableとRunnableの違い。
| 側面 | Runnable | Callable |
|---|---|---|
| 戻り値 | なし | あり |
| チェック例外 | なし | あり |
| パッケージ | java.lang | java.util.concurrent |
Callabletask = () -> 42; Future result = executor.submit(task); System.out.println(result.get());
27) プロデューサー・コンシューマー用BlockingQueue。
BlockingQueueはスレッドセーフなブロッキング操作を提供し、プロデューサー・コンシューマーパターンを簡素化。
BlockingQueuequeue = new ArrayBlockingQueue<>(10); new Thread(() -> queue.put(1)).start(); // Producer new Thread(() -> System.out.println(queue.take())).start(); // Consumer
- 手動
wait()/notify()排除。 - 有界・無界実装両対応。
28) スレッドスターベーションとライブロック。
スターベーションは低優先度スレッドがCPU時間を永遠に得られない状態。ライブロックはスレッドが継続的に状態を変化させるが進行しない状態。対策には公平ロック、ビジーウェイト回避、適切なスケジューリング。
29) マルチスレッドアプリケーション性能改善。
- スレッドプール使用。
- 同期スコープ削減。
- 並行データ構造活用。
- 不変オブジェクト優先。
- フォールスシェアリング回避。
- スレッド数をCPUコア数に調整。
- ブロッキング操作に非同期I/O使用。
30) 実世界のマルチスレッドシナリオ。
決済ゲートウェイで並行トランザクション処理を最適化:
- ExecutorServiceでワーカースレッド。
- ConcurrentHashMapでトランザクション状態。
- ReentrantLockでアカウントレベルロック。
- CountDownLatchでバッチ同期。
- CompletableFutureで非同期レスポンス。
結果:スループット35%向上、レイテンシ40%削減。
31) Javaの仮想スレッド。
Java 21で導入された仮想スレッドは、JVM管理の軽量スレッドで、最小オーバーヘッドで数百万の並行タスクを可能にします。
| 機能 | プラットフォームスレッド | 仮想スレッド |
|---|---|---|
| 管理主体 | OS | JVM |
| 生成コスト | 高 | 極めて低 |
| 並行レベル | 数千 | 数百万 |
| スケジューリング | OSレベル | JVM協調的 |
| ユースケース | CPUバウンドタスク | I/Oバウンド/高並行タスク |
Thread.startVirtualThread(() -> System.out.println("Virtual thread running"));
32) 構造化並行性。
Java 21でプレビュー。構造化並行性は複数の並行タスクを単一ユニットとして扱い、それらが一緒に開始、管理、終了することを保証。孤児スレッドを排除し、エラー伝播を簡素化。
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future user = scope.fork(() -> findUser()); Future order = scope.fork(() -> fetchOrderCount()); scope.join(); scope.throwIfFailed(); System.out.println(user.resultNow() + " has " + order.resultNow() + " orders."); }
33) Javaのリアクティブストリーム。
リアクティブストリームはデータストリーム処理のノンブロッキング、バックプレッシャー対応モデルを提供し、Project Reactor、RxJava、Spring WebFlux等フレームワークの基盤を形成。
Publisher– データ生成。Subscriber– データ消費。Subscription– フロー制御。Processor– パブリッシャー兼サブスクライバー。
Flow.Publisherpublisher = subscriber -> subscriber.onNext(42);
34) 適切なスレッド割り込み処理。
ループ内で常にThread.interrupted()をチェック、リソースクリーンアップ、InterruptedExceptionキャッチ後に割り込みステータス保持。
while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // フラグ復元 break; } }
35) 並列性 vs 並行性。
並行性は実行をインターリーブして複数タスクを管理、並列性は複数CPUコアでタスクを同時実行。
| 概念 | 定義 | 例 |
|---|---|---|
| 並行性 | タスクのインターリーブ | 1000クライアントリクエストを並行処理 |
| 並列性 | 同時実行 | CPUコア間で計算を実行 |
36) スレッドプロファイリングツールと技法。
| ツール | 目的 |
|---|---|
| jstack | スレッドダンプ取得 |
| jconsole / VisualVM | リアルタイム監視 |
| Java Flight Recorder (JFR) | 低オーバーヘッドプロファイリング |
| Mission Control (JMC) | JFR記録の可視化 |
| async-profiler | CPU & 割り当てプロファイリング |
| ThreadMXBean | プログラム的検査 |
ThreadMXBean bean = ManagementFactory.getThreadMXBean(); System.out.println(bean.getThreadCount());
37) 一般的なパフォーマンスボトルネック。
- 過度なロック競合。
- 変数のフォールスシェアリング。
- コンテキストスイッチオーバーヘッド。
- 不適切な同期。
- volatile変数の過剰使用。
最適化には細粒度ロック、ロックフリー構造、スレッド生成最小化、スレッドローカルストレージ使用が含まれます。
38) ロックフリー、ウェイトフリー、オブストラクションフリーアルゴリズム。
| タイプ | 定義 | 保証 |
|---|---|---|
| ロックフリー | 少なくとも1スレッドが進行。 | システム全体の進行。 |
| ウェイトフリー | 全スレッドが有限ステップで進行。 | 最強保証。 |
| オブストラクションフリー | 競合不在時進行。 | 最弱保証。 |
AtomicInteger操作はロックフリー;ブロッキングキューはロック使用。
39) ForkJoinPool内部構造。
各ワーカーが独自のデックを維持;アイドルワーカーが他からタスクを盗み、競合削減とスループット向上。
ForkJoinPool pool = new ForkJoinPool(); pool.submit(() -> IntStream.range(0, 100).parallel().forEach(System.out::println));
40) 1秒間に数百万リクエストを処理する高並行システム設計。
- 軽量リクエスト処理用仮想スレッド。
- 非同期I/O用リアクティブストリーム。
- 予測可能なタスクライフサイクル用構造化並行性。
- 高性能キャッシュ(ConcurrentHashMap、Caffeine)。
- スレッドセーフキュー(Disruptor、BlockingQueue)。
- JFR & JMCで監視。
- 非同期ワークフロー用CompletableFuture。
結果:最小ブロッキングと最適リソース使用で数百万同時接続を実現。
🔍 実世界シナリオと戦略的回答付きトップJavaマルチスレッド面接質問
以下は10の現実的な質問、面接官の期待、洗練されたサンプル回答です。
1) Javaにおけるプロセスとスレッドの違いは?
候補者はOSとJVMの基礎、メモリ使用、実行フローを説明すべき。例:ブラウザプロセスはレンダリング、ネットワーク、ユーザー入力用の複数スレッドを含む。
2) synchronizedキーワードの目的は?
並行制御、イントリンシックロック、スレッドセーフティを説明。クリティカルセクションへのアクセスを一度に1スレッドのみに保証。
3) 直面した困難なマルチスレッド問題と解決方法?
デッドロックシナリオ、スレッドダンプでの特定方法、一貫したロック順序強制による解決を記述。
4) Javaメモリモデルと可視性?
happens-before関係、volatile、可視性と順序性を保証する同期構造を説明。
5) wait()、notify()、notifyAll()の違い?
スレッド間通信とモニターメカニズムを説明。
6) マルチスレッドアプリケーションの最適化?
ロック競合特定、synchronizedをConcurrentHashMapに置換、測定可能なスループット向上を提示。
7) 共有データ構造の安全な更新?
スレッドセーフコレクションまたはReentrantLockでの明示的ロックで粒度制御。
8) ExecutorServiceの役割?
ワーカースレッドプール管理、オーバーヘッド削減、ライフサイクル管理簡素化。
9) レースコンディションのトラブルシューティング?
負荷下で再現、ログ強化、適切な同期追加で修正。
10) 多様な優先度を持つマルチスレッドソリューション設計?
カスタムコンパレーター付き優先度キューとThreadPoolExecutorで高優先度タスク対応。
Java
- Javaアクセス修飾子の完全ガイド:種類、ルール、実践例
- Java文字列をマスター:生成、メソッド、ベストプラクティス
- Javaマルチスレッド面接トップ40問と回答 – 2026年版
- Java 10のガベージコレクターインターフェースとG1並列フルGCでメモリ管理を効率化
- JDBC面接対策:必須50問&エキスパート回答(2026年版)
- Java 9プロセスAPIの改善:ProcessHandleで詳細情報取得
- Java マルチスレッド完全解説:概念、ライフサイクル、実践コード例
- Java 8 Base64エンコーディング:シンプル、URL、MIME対応が標準搭載
- Java Writerクラス:文字ストリームをマスターする
- Java変数の種類:ローカル、インスタンス、クラス変数を徹底解説
- Java 10でルート証明書を標準搭載:OpenJDKでTLSがデフォルト動作