问题
Consider this code from TIJ 4th edition
class SleepBlocked implements Runnable {
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; }
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() {
public void run() {
f(); // Lock acquired by this thread
}
}.start();
}
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);
}
}
Here is the output
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)
Here you can see that all the created threads have been interrupted at last(atleast that's what I think because no one execute its run method to last) but instead after that Bruce Eckel keeps on saying that
you cannot interrupt a task that is trying to acquire a synchronized lock or one that is trying to perform I/O.
Or does interrupt means something else here??
Also he stated that
SleepBlock is an example of interruptible blocking, whereas IOBlocked and SynchronizedBlocked are uninterruptible blocking.
What does he mean by uninterruptible blocking here? Can anyone specify the difference between two?
回答1:
He is out of date, or your edition is. NIO supports interruptible I/O, via InterruptibleChannel, although only in the rather useless way that the channel gets closed, due to the ludicrous Linux interrupt semantics.
java.io
and java.net
I/O operations are not subject to interrupts, and there is nothing in your question that proves otherwise. If they were, you would have seen "Interrupted from blocked I/O"
in the output, and you didn't. Your I/O thread is still blocked in in.read()
.
来源:https://stackoverflow.com/questions/47957606/what-is-uninterruptible-blocking