複数のブロックスレッドを同時に中断する場合コード

3234 ワード

マルチスレッドをブロックする場合はいろいろあります
中断可能なsleep()方式があります.
中断できないIOと同期方式があります.
java.util.ContcurrentはExecutorServicesを提供します.submit()は、単一スレッドを実行するために実行可能なコンテキストFutureを返します.Futureにより閉塞を中断することができるFuture.cancle(true);

package com.text;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

//sleep  
class SleepBlocked implements Runnable {

	public void run() {
		try {
			TimeUnit.SECONDS.sleep(100);
		} catch (InterruptedException e) {
			System.out.println("InterruptedException");
		}
		System.out.println("Exiting SleepBlocked.run()");
	}

}

// IO  
class InputBlocked implements Runnable {

	private InputStream in;

	public InputBlocked(InputStream is) {
		this.in = is;
	}

	public void run() {
		try {
			System.out.println("Waiting for read()");
			in.read();
		} catch (IOException e) {
			if (Thread.currentThread().isInterrupted()) {
				System.out.println("Interrupted from blocked I/O");
			} else {
				throw new RuntimeException(e);
			}
		}
		System.out.println("Exiting InputBlocked.run");
	}
}
// 
class SynchronizedBlocked implements Runnable {

	private synchronized void f() {
		while (true) {
			Thread.yield();
		}
	}

	public SynchronizedBlocked() {
		new Thread() {
			public void run() {
				f();
			}
		}.start();
	}

	public void run() {
		System.out.println("Trying call the f()");
		f();
		System.out.println("Exiting SynchronizedBlocked.run()");
	}
}

public class Interrupting {

	private static ExecutorService exec = Executors.newCachedThreadPool();

	static void test(Runnable r) throws InterruptedException {
		Future<?> t = exec.submit(r);
		TimeUnit.SECONDS.sleep(100);
		System.out.println("Interrupting " + r.getClass().getName());
		t.cancel(true);
		System.out.println("Interrupt sent to " + r.getClass().getName());
	}

	public static void main(String[] args) throws InterruptedException {
		test(new SleepBlocked());
		test(new InputBlocked(System.in));
		test(new SynchronizedBlocked());
		TimeUnit.SECONDS.sleep(3);
		System.out.println("Aborting with System.exit(0)");
		System.exit(0);
	}
}


印刷結果は次のとおりです.
Interrupting com.text.SleepBlocked
Interrupt sent to com.text.SleepBlocked
Exiting SleepBlocked.run()
Waiting for read()
Interrupting com.text.InputBlocked
Interrupt sent to com.text.InputBlocked
Trying call the f()
Interrupting com.text.SynchronizedBlocked
Interrupt sent to com.text.SynchronizedBlocked
Aborting with System.exit(0)
IOと同期方式のブロックは中断できないことがわかる.