はじめに
まずはじめに、「無限ループ=悪」ではない!!
ゲームのコマンド待ち、サーバーの受け付け、UIのイベント待ちなど、
ずっと動いていてほしい処理はたくさんある。
大事なのは、安全に止められる仕組みと回し方の設計。
この記事では while(true)
を“こわくない形”で使うコツと、
break
/ continue
/ ラベル付きbreak をまとめていくよ。
🎓 無限ループってなに?
while (true) {
// ずっと繰り返す
}
- 目的: 常時待ち受け・常時監視・常時描画など。
- 鍵: いつでも抜けられる 終了条件 と、暴走しない 節度(スリープやブロッキングIO)。
🔧 正しい回し方(設計パターン)
- フラグで管理
boolean running = true;
while (running) {
String cmd = nextCommand(); // 入力待ち(ブロッキング)
if (cmd == null) break; // EOFなど
if (cmd.isBlank()) continue; // 空入力はスキップ
if (cmd.equals("quit")) running = false; // 次の周で抜ける
handle(cmd);
}
2 . 監視カウンタで保険
int guard = 10_000; // 回り過ぎ防止
while (condition && guard-- > 0) {
// ...
}
guard は「最大で何周まで」の上限。
guard-- > 0
は「今の guard が 0 より大きいかを見て、判定のあとで1減らす」という意味(後置デクリメント)。
3 . タイムアウトをつける
long deadline = System.currentTimeMillis() + 5_000; // 最大5秒
while (!ready() && System.currentTimeMillis() < deadline) {
try { Thread.sleep(50); } catch (InterruptedException ignored) {}
}
if (!ready()) System.out.println("タイムアウト");
4 . CPUを休ませる(スピンしない)
while (queue.isEmpty()) {
try { Thread.sleep(10); } catch (InterruptedException ignored) {}
}
// あるいはブロッキングAPIを使う
// Message msg = queue.take(); // 取り出しまでブロック
⚡ ピカチュウ例:コマンドループ(quitで終了)
import java.util.Scanner;
public class CommandLoop {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("> ");
String cmd = sc.nextLine().trim();
if (cmd.isEmpty()) continue; // 何も入力されなければ次へ
if (cmd.equals("quit")) break; // ここで抜ける
if (cmd.equals("heal")) heal();
else System.out.println("知らないコマンド: " + cmd);
}
System.out.println("バイバイ!");
}
static void heal() { System.out.println("ピカチュウは元気になった!"); }
}
ポイント:continue
は“その周の残りをスキップ”、break
は“ループ自体から脱出”。
🧭 ラベル付き break:多重ループを一気に抜ける(while版)
Javaのラベルは 文の直前に置く識別子 + コロン の形。探索系で便利だよ。
int H = 10, W = 10;
int[][] cave = new int[H][W]; // 0: 通路, 1: 野生ポケモン
cave[4][7] = 1; // どこかに出現!
search: // ← ラベル
int y = 0;
while (y < H) {
int x = 0;
while (x < W) {
if (cave[y][x] == 1) {
System.out.println("発見! (" + y + "," + x + ")");
break search; // 二重ループごと脱出!
}
x++;
}
y++;
}
System.out.println("探索おしまい");
continue search;
と書けば、外側の次の周へスキップもできる。
🧪 continue の使いどころ(while版)
- 無視したいデータを早めに弾く“早期スキップ”
int i = 0;
while (i < party.size()) {
String name = party.get(i);
if (name == null || name.isBlank()) { i++; continue; } // 無名は飛ばす
System.out.println(name + " を先頭に!");
i++;
}
- ゲームログのノイズを抑える
int j = 0;
while (j < events.size()) {
Event e = events.get(j);
if (e.type() == Event.Type.DEBUG) { j++; continue; } // デバッグ行は出さない
log(e);
j++;
}
🪄 次回予告
次は 実務でのwhile活用。入力バリデーション/JDBCの逐次取得/状態待ちに、
今回のテクニックをどう落とし込むかをまとめるよ!
ピッピカチュウ!!
あとがき
ここまで読んでくれて、本当にありがとうございました。
「プログラミングって難しい…」って思ってた人も、
「ちょっと楽しいかも…!」って思ってもらえたらうれしいな。
次の投稿も、よろしくおねがいします。
💬 コメント・フィードバック歓迎!
「この章わかりやすかった!」
「これ表現まちがってない?」
「次は○○をやってほしい!」などなど、
お気軽にコメントで教えてくださいね!