Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何编写响应“Thread.interrupt()”的本机代码?_Java_Multithreading_Java Native Interface_Interrupted Exception - Fatal编程技术网

Java 如何编写响应“Thread.interrupt()”的本机代码?

Java 如何编写响应“Thread.interrupt()”的本机代码?,java,multithreading,java-native-interface,interrupted-exception,Java,Multithreading,Java Native Interface,Interrupted Exception,在Java中,所有标准的阻塞方法都可以通过调用Thread.interrupt()来中断,但是如果我们有Java绑定来包装一个自己进行I/O的本机库呢?那么本机代码应该如何钩住线程并响应对Thread.interrupt()的调用?示例代码 有关完整的可写性,包括可运行的示例代码,请参阅 Thread.interrupt()如何工作? 在Sun的JRE(和OpenJDK)中,interrupt()能够唤醒一些低级操作本身,例如等待监视器(Object.wait()),并为高级代码提供一个内部钩子

在Java中,所有标准的阻塞方法都可以通过调用
Thread.interrupt()
来中断,但是如果我们有Java绑定来包装一个自己进行I/O的本机库呢?那么本机代码应该如何钩住线程并响应对
Thread.interrupt()
的调用?

示例代码 有关完整的可写性,包括可运行的示例代码,请参阅

Thread.interrupt()
如何工作? 在Sun的JRE(和OpenJDK)中,
interrupt()
能够唤醒一些低级操作本身,例如等待监视器(
Object.wait()
),并为高级代码提供一个内部钩子,以通知中断。这是通过
JavaLangAccess.blockedOn()
提供的,如果您愿意使用sun特定的实现细节,您的代码实际上可以通过
sun.misc.SharedSecrets
直接调用它

据我所知,只有一种公开的、有文档记录的方法可以注册该通知,那就是使用
java.nio.channels.spi.AbstractSelector
。这是
Selector
的部分实现,它为您连接
JavaLangAccess.blockedOn()
通知到选择器的
wakeup()
方法做了大量的工作

如何实现这一切 实现
AbstractSelector
来制作您自己的选择器;大多数方法都不相关,所以只需忽略它们并放入存根即可关闭编译器。当您准备输入JNI阻塞方法时,调用
AbstractSelector
begin()
方法,然后在JNI调用返回时调用
end()

选择器应该在其
wakeup()的实现中取消JNI方法

粗码 (有关完整的运行示例,请参见顶部链接的github repo。)

class-NativeTask{
公共NativeTask(){}
公共void doTask()
抛出中断异常{
NativeTaskSelector=新的NativeTaskSelector(此);
试一试{
selector.registerStart();
doTask0();//本机方法
if(Thread.interrupted())
抛出新的InterruptedException();
}最后{
selector.registerEnd();
尝试{selector.close();}catch(IOException不可能){}
}
}
/*长期运行的本机操作*/
本机私有void doTask0();
public void wakeupTask(){wakeupTask0();}
/*使本机操作唤醒的一种方法*/
本机私有void wakeupTask0();
}
类NativeTaskSelector扩展了AbstractSelector{
受保护的NativeTaskSelector(NativeTask任务){
超级(空);
任务=任务;
}
public void registerStart(){begin();}
public void registerId(){end();}
最终私有任务;
@凌驾
公共选择器唤醒(){
task.wakeupTask();
归还这个;
}
@凌驾
受保护的void implCloseSelector()引发IOException{
}
@凌驾
受保护的SelectionKey寄存器(AbstractSelectableChannel arg0、int arg1、,
对象(arg2){
抛出新的UnsupportedOperationException();
}
@凌驾
公共设置密钥(){
抛出新的UnsupportedOperationException();
}
@凌驾
public int select()引发IOException{
抛出新的UnsupportedOperationException();
}
@凌驾
公共整数选择(长arg0)引发IOException{
抛出新的UnsupportedOperationException();
}
@凌驾
public int selectNow()引发IOException{
抛出新的UnsupportedOperationException();
}
@凌驾
公共集合选择键(){
抛出新的UnsupportedOperationException();
}
}
class NativeTask {
    public NativeTask() {}

    public void doTask()
            throws InterruptedException {
        NativeTaskSelector selector = new NativeTaskSelector(this);
        try {
            selector.registerStart();
            doTask0(); // native method
            if (Thread.interrupted())
                    throw new InterruptedException();
        } finally {
            selector.registerEnd();
            try { selector.close(); } catch (IOException impossible) {}
        }
    }
    /* The long-running native operation. */
    native private void doTask0();

    public void wakeupTask() { wakeupTask0(); }
    /* A way to cause the native operation to wake up. */
    native private void wakeupTask0();
}

class NativeTaskSelector extends AbstractSelector {

    protected NativeTaskSelector(NativeTask task_) {
        super(null);
        task = task_;
    }

    public void registerStart() { begin(); }
    public void registerEnd() { end(); }

    final private NativeTask task;

    @Override
    public Selector wakeup() {
        task.wakeupTask();
        return this;
    }

    @Override
    protected void implCloseSelector() throws IOException {
    }

    @Override
    protected SelectionKey register(AbstractSelectableChannel arg0, int arg1,
            Object arg2) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set<SelectionKey> keys() {
        throw new UnsupportedOperationException();
    }

    @Override
    public int select() throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public int select(long arg0) throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public int selectNow() throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set<SelectionKey> selectedKeys() {
        throw new UnsupportedOperationException();
    }

}