スレッドのライフサイクルと操作
1. スレッドの安全な停止
JDKが提供するstop()やdestroy()は非推奨です。代わりに、フラグ変数による協調的終了を実装します。
public class GracefulShutdown implements Runnable {
private volatile boolean active = true;
@Override
public void run() {
int counter = 0;
while (active) {
System.out.println("Task running: " + counter++);
}
}
public void requestStop() {
this.active = false;
}
public static void main(String[] args) {
GracefulShutdown task = new GracefulShutdown();
Thread worker = new Thread(task);
worker.start();
for (int i = 0; i < 100; i++) {
if (i == 75) {
task.requestStop();
System.out.println("Shutdown requested...");
}
System.out.println("Main thread: " + i);
}
}
}
2. スレッドの一時停止(Sleep)
Thread.sleep()は指定ミリ秒間スレッドを待機させますが、ロックは保持したままです。時間経過後、Runnable状態に戻ります。
import java.text.SimpleDateFormat;
import java.util.Date;
public class ClockTicker {
public static void main(String[] args) {
while (true) {
try {
Thread.sleep(1000);
String now = new SimpleDateFormat("HH:mm:ss").format(new Date());
System.out.println("Current time: " + now);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
}
}
}
3. スレッドの礼譲(Yield)
Thread.yield()は現在のスレッドを一時的にRunnable状態に戻し、他のスレッドに実行機会を与えます。ただし、スケジューラ次第で同じスレッドが再選択される可能性があります。
public class CooperativeYield implements Runnable {
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + ": starting");
Thread.yield();
System.out.println(name + ": resumed after yield");
}
public static void main(String[] args) {
Thread t1 = new Thread(new CooperativeYield(), "Worker-A");
Thread t2 = new Thread(new CooperativeYield(), "Worker-B");
t1.start(); t2.start();
}
}
4. スレッドの結合(Join)
join()は呼び出し元スレッドをブロックし、対象スレッドの終了を待ちます。これにより並列処理を直列化できます。
public class SequentialExecution implements Runnable {
@Override
public void run() {
for (int step = 1; step <= 5; step++) {
System.out.println("Subtask #" + step);
}
}
public static void main(String[] args) throws InterruptedException {
Thread background = new Thread(new SequentialExecution());
background.start();
for (int i = 1; i <= 10; i++) {
if (i == 3) {
System.out.println("Waiting for background task...");
background.join();
}
System.out.println("Main step: " + i);
}
}
}
5. スレッド状態の監視
JavaではThread.getState()で以下の6状態を取得可能です:
- NEW:生成済みだが未開始
- RUNNABLE:実行可能または実行中
- BLOCKED:ロック待ち
- WAITING:無期限待機中
- TIMED_WAITING:時間制限付き待機中
- TERMINATED:終了済み
public class StateMonitor implements Runnable {
@Override
public void run() {
try { Thread.sleep(3000); }
catch (InterruptedException e) { Thread.currentThread().interrupt(); }
}
public static void main(String[] args) {
Thread monitor = new Thread(new StateMonitor());
System.out.println("Initial: " + monitor.getState());
monitor.start();
System.out.println("After start: " + monitor.getState());
while (monitor.isAlive()) {
try { Thread.sleep(500); }
catch (InterruptedException e) { break; }
System.out.println("Current: " + monitor.getState());
}
System.out.println("Final: " + monitor.getState());
}
}