目录
InterruptibleChannel
package java.nio.channels;
import java.io.IOException;
/**
* 可以异步关闭和中断的通道。
*
* <p> 实现此接口的通道是异步关闭的:
* 如果一个线程在可中断通道上的I/O操作中被阻塞,
* 那么另一个线程可能会调用该通道的关闭方法。
* 这将导致阻塞的线程接收一个AsynchronousCloseException异常。
*
* <p> 实现此接口的通道也是可中断的:
* 如果一个线程在可中断通道上的I/O操作中被阻塞,那么另一个线程可能会调用被阻塞线程的interrupt方法。
* 这将导致通道被关闭,阻塞线程接收一个ClosedByInterruptException异常,并且阻塞线程的中断状态被设置。
*
* <p> 如果一个线程的中断状态已经设置,它调用一个阻塞的I/O操作,然后通道将被关闭,
* 线程将立即收到一个ClosedByInterruptException;
* 它的中断状态将保持设置。
*
* <p> 通道在(且仅在)实现此接口时支持异步关闭和中断。
* 如果有必要,可以在运行时通过instanceof操作符进行测试。
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public interface InterruptibleChannel
extends Channel
{
/**
* 关闭这个通道。
*
* <p> 当前在此通道上的I/O操作中阻塞的任何线程都将接收到一个AsynchronousCloseException异常。
*
* <p> 否则,此方法的行为将与Channel接口所指定的完全相同。</p>
*
* @throws IOException If an I/O error occurs
*/
public void close() throws IOException;
}
AbstractInterruptibleChannel
package java.nio.channels.spi;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.nio.channels.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.nio.ch.Interruptible;
/**
* 可中断通道的基本实现类。
*
* <p> 这个类封装了实现通道的异步关闭和中断所需的底层机制。
* 具体的通道类必须分别在调用可能阻塞的I/O操作之前和之后调用begin和end方法。
* 为了确保end方法总是被调用,这些方法应该在try中使用。finally块:
*
* <blockquote><pre>
* boolean completed = false;
* try {
* begin();
* completed = ...; // Perform blocking I/O operation
* return ...; // Return result
* } finally {
* end(completed);
* }</pre></blockquote>
*
* <p> end方法的已完成参数说明I/O操作是否实际完成,也就是说,它是否对调用程序有任何可见的效果。
* 例如,在一个读取字节的操作的情况下,这个参数应该是真的,
* 如果,并且仅当,一些字节实际上被转移到调用者的目标缓冲区。
*
* <p> 具体的channel类还必须实现implCloseChannel方法,
* 如果它被调用,而另一个线程在本地I/O操作中被阻塞,那么该操作将立即返回,要么抛出异常,要么正常返回。
* 如果线程被中断,或者阻塞线程的通道被异步关闭,那么通道的end方法将抛出相应的异常。
*
* <p>这个类执行实现Channel所需的同步规范。
* implCloseChannel方法的实现不需要与可能试图关闭通道的其他线程同步。</p>
*
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class AbstractInterruptibleChannel
implements Channel, InterruptibleChannel
{
private final Object closeLock = new Object();
private volatile boolean open = true;
/**
* 初始化此类的新实例
*/
protected AbstractInterruptibleChannel() { }
/**
* 关闭这个通道。
*
* <p> 如果通道已经关闭,则此方法立即返回。
* 否则,它将通道标记为closed,然后调用implCloseChannel方法来完成close操作。</p>
*
* @throws IOException
* If an I/O error occurs
*/
public final void close() throws IOException {
synchronized (closeLock) {
if (!open)
return;
open = false;
implCloseChannel();
}
}
/**
* 关闭这个通道。
*
* <p> 该方法由close方法调用,以执行关闭通道的实际工作。
* 只有在通道尚未关闭的情况下才会调用此方法,并且只调用一次。
*
* <p> 此方法的实现必须安排,在此通道上的I/O操作中阻塞的任何其他线程,将立即返回,
* 可以通过抛出异常,也可以通过正常返回。
* </p>
*
* @throws IOException
* If an I/O error occurs while closing the channel
*/
protected abstract void implCloseChannel() throws IOException;
public final boolean isOpen() {
return open;
}
// -- Interruption 机制 --
private Interruptible interruptor;
private volatile Thread interrupted;
/**
* 标记可能无限期阻塞的I/O操作的开始。
*
* <p> 该方法应该与end方法一起调用,使用try…finally,
* 阻塞如上所示,以实现该通道的异步丢失和中断。</p>
*/
protected final void begin() {
if (interruptor == null) {
// interruptor 单例模式,设置一个interruptor
interruptor = new Interruptible() {
// target是导致其他线程interrupt的线程
public void interrupt(Thread target) {
synchronized (closeLock) {
if (!open)
return;
// 对通道执行关闭操作,设置interrupted
open = false;
interrupted = target;
try {
AbstractInterruptibleChannel.this.implCloseChannel();
} catch (IOException x) { }
}
}};
}
// 会在interruptor上阻塞
blockedOn(interruptor);
Thread me = Thread.currentThread();
// 如果当前线程已经是Interrupted,调用interruptor.interrupt(me)
if (me.isInterrupted())
interruptor.interrupt(me);
}
/**
* 标记可能无限期阻塞的I/O操作的结束。
*
* <p> 该方法应该与begin方法一起调用,使用try…finally,如上所示的区块,以实现该通道的异步丢失和中断。
*
* @param completed
* <tt>true</tt> if, and only if, the I/O operation completed
* successfully, that is, had some effect that would be visible to
* the operation's invoker
*
* @throws AsynchronousCloseException
* If the channel was asynchronously closed
*
* @throws ClosedByInterruptException
* If the thread blocked in the I/O operation was interrupted
*/
protected final void end(boolean completed)
throws AsynchronousCloseException
{
// 清空阻塞的东西(原来是interruptor)
blockedOn(null);
Thread interrupted = this.interrupted;
// 如果interrupted不为null,而且是线程自己,清空interrupted,抛出ClosedByInterruptException
if (interrupted != null && interrupted == Thread.currentThread()) {
interrupted = null;
throw new ClosedByInterruptException();
}
// 如果IO操作未完成,并且通道已关闭,抛出AsynchronousCloseException
if (!completed && !open)
throw new AsynchronousCloseException();
}
// -- sun.misc.SharedSecrets --
static void blockedOn(Interruptible intr) { // package-private
sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(),
intr);
}
}