2015-04-20 15:36:01 -07:00
|
|
|
//: concurrency/Interrupting.java
|
|
|
|
// Interrupting a blocked thread.
|
|
|
|
import java.util.concurrent.*;
|
|
|
|
import java.io.*;
|
|
|
|
import static net.mindview.util.Print.*;
|
|
|
|
|
|
|
|
class SleepBlocked implements Runnable {
|
2015-05-05 11:20:13 -07:00
|
|
|
@Override
|
2015-04-20 15:36:01 -07:00
|
|
|
public void run() {
|
|
|
|
try {
|
|
|
|
TimeUnit.SECONDS.sleep(100);
|
|
|
|
} catch(InterruptedException e) {
|
|
|
|
print("InterruptedException");
|
|
|
|
}
|
|
|
|
print("Exiting SleepBlocked.run()");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class IOBlocked implements Runnable {
|
|
|
|
private InputStream in;
|
|
|
|
public IOBlocked(InputStream is) { in = is; }
|
2015-05-05 11:20:13 -07:00
|
|
|
@Override
|
2015-04-20 15:36:01 -07:00
|
|
|
public void run() {
|
|
|
|
try {
|
|
|
|
print("Waiting for read():");
|
|
|
|
in.read();
|
|
|
|
} catch(IOException e) {
|
|
|
|
if(Thread.currentThread().isInterrupted()) {
|
|
|
|
print("Interrupted from blocked I/O");
|
|
|
|
} else {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
print("Exiting IOBlocked.run()");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class SynchronizedBlocked implements Runnable {
|
|
|
|
public synchronized void f() {
|
|
|
|
while(true) // Never releases lock
|
|
|
|
Thread.yield();
|
|
|
|
}
|
|
|
|
public SynchronizedBlocked() {
|
|
|
|
new Thread() {
|
2015-05-05 11:20:13 -07:00
|
|
|
@Override
|
2015-04-20 15:36:01 -07:00
|
|
|
public void run() {
|
|
|
|
f(); // Lock acquired by this thread
|
|
|
|
}
|
|
|
|
}.start();
|
|
|
|
}
|
2015-05-05 11:20:13 -07:00
|
|
|
@Override
|
2015-04-20 15:36:01 -07:00
|
|
|
public void run() {
|
|
|
|
print("Trying to call f()");
|
|
|
|
f();
|
|
|
|
print("Exiting SynchronizedBlocked.run()");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class Interrupting {
|
|
|
|
private static ExecutorService exec =
|
|
|
|
Executors.newCachedThreadPool();
|
|
|
|
static void test(Runnable r) throws InterruptedException{
|
|
|
|
Future<?> f = exec.submit(r);
|
|
|
|
TimeUnit.MILLISECONDS.sleep(100);
|
|
|
|
print("Interrupting " + r.getClass().getName());
|
|
|
|
f.cancel(true); // Interrupts if running
|
|
|
|
print("Interrupt sent to " + r.getClass().getName());
|
|
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
|
test(new SleepBlocked());
|
|
|
|
test(new IOBlocked(System.in));
|
|
|
|
test(new SynchronizedBlocked());
|
|
|
|
TimeUnit.SECONDS.sleep(3);
|
|
|
|
print("Aborting with System.exit(0)");
|
|
|
|
System.exit(0); // ... since last 2 interrupts failed
|
|
|
|
}
|
|
|
|
} /* Output: (95% match)
|
|
|
|
Interrupting SleepBlocked
|
|
|
|
InterruptedException
|
|
|
|
Exiting SleepBlocked.run()
|
|
|
|
Interrupt sent to SleepBlocked
|
|
|
|
Waiting for read():
|
|
|
|
Interrupting IOBlocked
|
|
|
|
Interrupt sent to IOBlocked
|
|
|
|
Trying to call f()
|
|
|
|
Interrupting SynchronizedBlocked
|
|
|
|
Interrupt sent to SynchronizedBlocked
|
|
|
|
Aborting with System.exit(0)
|
|
|
|
*///:~
|