[本文是我对Java Concurrency In Practice 7.1的归纳和总结. 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正. ]
并不是所有的阻塞都是可中断的, 比如InputStream.read方法. 在检测到输入数据可用, 到达流末尾或者抛出异常前, 该方法一直阻塞. 而且阻塞的时候不会检查中断标记, 所以中断线程无法使read从阻塞状态返回. 但是关闭流可以使得read方法抛出异常, 从而从阻塞状态返回.
public class ReaderThread extends Thread {
private static final int BUFSZ = 1024;
private final Socket socket;
private final InputStream in;
public ReaderThread(Socket socket) throws IOException {
this.socket = socket;
this.in = socket.getInputStream();
}
// 覆盖Thread类的interrupt方法, 加入关闭socket的代码
// 如果发生中断时, 线程阻塞在read方法上, socket的关闭会导致read方法抛出SocketException, 然后run方法运行完毕
public void interrupt() {
try {
socket.close();
} catch (IOException ignored) {
} finally {
super.interrupt();
}
}
public void run() {
try {
byte[] buf = new byte[BUFSZ];
while (true) {
int count = in.read(buf);
if (count < 0)
break;
else if (count > 0)
processBuffer(buf, count);
}
} catch (IOException e) { /* Allow thread to exit */
}
}
private void processBuffer(byte[] buf, int count) {
//...
}
}
如果task并非在自己创建的线程里运行, 而是提交给线程池运行的话, 就无法使用上例的方式处理不可中断阻塞了. 之前有过分析, 对于提交给线程池执行的task, 应该通过Future.cancel方法提前终止task的运行, 所以可以考虑重写Future.cancel方法, 在其中加入关闭socket的操作. Future对象是由submit方法返回的, 其源代码如下:
public <T> Future<T> submit(Callable<T> task) {
if (task == null)
throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
可知submit方法返回的Future对象是调用newTaskFor方法获得的:
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
newTaskFor方法被声明为protected, 所以我们可以通过继承覆盖该方法, 返回自定义的Future对象.
首先将需要覆盖的2个方法定义在接口中:
public interface CancellableTask<T> extends Callable<T> {
void cancel();
RunnableFuture<T> newTask();
}
然后让task类实现CancellableTask接口:
public abstract class SocketUsingTask<T> implements CancellableTask<T> {
private Socket socket;
protected synchronized void setSocket(Socket s) {
socket = s;
}
public synchronized void cancel() {
try {
if (socket != null)
socket.close();
} catch (IOException ignored) {
}
}
public RunnableFuture<T> newTask() {
return new FutureTask<T>(this) {
// 定义FutureTask的匿名内部类, 并覆盖cancel方法, 向其中加入关闭socket的操作
public boolean cancel(boolean mayInterruptIfRunning) {
try {
SocketUsingTask.this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}
接着继承ThreadPoolExecutor类并覆盖newTaskFor方法, 让该方法返回自定义的FutureTask对象:
public class CancellingExecutor extends ThreadPoolExecutor {
// ...
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
// 如果callable是CancellableTask对象, 那么就返回自定义的FutureTask(通过调用其newTaskFor方法实现)
if (callable instanceof CancellableTask)
return ((CancellableTask<T>) callable).newTask();
else
return super.newTaskFor(callable);
}
}
测试代码:
public static void main(String[] args) {
CancellingExecutor executor = new CancellingExecutor();
SocketUsingTask task = new SocketUsingTask();
task.setSocket(new Socket("www.baidu.com", 80));
Future<V> future = executor.submit(task);
future.cancel(true);
}
分享到:
相关推荐
在i2active_node-7.1项目中,我们可以预期它会利用Node.js的事件驱动模型来处理并发请求,通过监听和响应事件来实现非阻塞I/O操作。这种模式对于处理大量并发连接非常有效,尤其适合构建高并发的实时应用,如聊天...
底半部(Delayed Work)机制则用于将耗时较长的任务从ISR中分离出来,避免阻塞中断处理。 中断处理的数据结构,如中断描述符表(Interrupt Descriptor Table, IDT)和中断处理程序指针,是用来管理和定位中断处理代码的...
在Linux设备驱动程序中,中断处理是不可或缺的部分,因为它允许设备在非阻塞状态下执行任务,提高系统的并行性和效率。 1. **中断概述**:中断分为硬件中断和服务请求(Software Interrupts, SoftIRQs)。硬件中断...
《Linux中断:中断嵌套...然而,正确地设计和实现中断处理程序,避免长时间阻塞中断,是确保系统稳定运行的关键。在编写驱动程序时,需要充分理解这些概念,并合理地利用内核提供的机制,以保证中断处理的高效和准确。
同时,中断处理函数的编写必须高效且避免阻塞,因为中断处理是上下文切换的关键点,影响系统的实时性。 此外,中断处理还可以涉及中断共享、中断底半部(SoftIRQs)和任务队列(Tasklets)等概念,这些在更复杂的...
1. **异步操作**:aiotrello库基于Python的asyncio库构建,支持非阻塞I/O,这意味着它能够在等待网络操作时执行其他任务,提高了程序的效率和响应速度。 2. **Trello API封装**:该库提供了对Trello API的全面封装...
这个话题对于嵌入式系统开发者来说是至关重要的,因为它涉及到硬件中断处理,这是实时系统中不可或缺的一部分。 首先,Mini2440是一款基于S3C2440 ARM9处理器的开发板,具有128MB内存,广泛用于嵌入式系统的学习和...
1. **事件驱动**:Node.js基于Chrome V8引擎,采用事件驱动、非阻塞I/O模型,使其在处理高并发请求时表现出色。 2. **单线程与异步编程**:Node.js的主要工作方式是异步编程,避免了线程上下文切换的开销,提升了...
"微信小程序-图书馆写笔记源码.zip" 是一个包含构建微信小程序的源代码文件的压缩包,专门用于创建一个图书馆笔记功能的小程序。 在微信小程序的开发过程中,主要涉及以下几个核心知识点: 1. **微信开发者工具**...
- **避免死锁**:确保中断服务程序不会长时间运行,防止阻塞其他中断。 - **同步问题**:中断处理时要防止数据竞争,可能需要使用锁或信号量来保护共享资源。 - **中断优先级**:合理设置中断优先级,保证高...
对于触摸事件处理、界面动态更新等方面的知识也是必不可少的。 8. **权限管理**:在Android中,访问网络和读写存储都需要用户的权限。因此,源码中可能包含了请求这些权限的代码。 9. **版本控制**:由于这是一个...
- ISR应该尽可能简洁,避免长时间阻塞其他中断。 - 在ISR中,通常需要保存和恢复CPU的状态,以防止中断嵌套时的混乱。 - 完成处理后,通常会清除中断标志,以防重复触发中断。 5. **中断程序的实现步骤** - **...
非阻塞中断不等待当前指令执行完毕就能立即响应,常用于处理紧急情况。快速中断则提供了更高效的中断处理路径,适用于需要快速响应的场合。 8. 中断虚拟化: 在虚拟化环境中,虚拟机监控器(VMM)需要模拟中断处理...
队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当完成后告知你 自动的socket接收。如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接 委托(delegate)支持。...
3. **中断处理**:RT-Thread提供了中断管理框架,需要根据目标硬件实现中断向量表和中断处理函数。中断服务例程应遵循RTOS的规则,避免长时间阻塞调度。 4. **内存管理**:RTOS内核需要一个内存管理系统,用于动态...
这种模式在处理大量并发连接时非常高效,因为系统可以同时处理多个请求,而不需要为每个请求分配独立的线程或进程。 协程是Swoole中的另一个关键概念。不同于线程或进程,协程是一种轻量级的并发机制,它们在同一...
在实际应用中,要确保中断服务例程的简洁高效,避免长时间运行的任务,防止阻塞其他中断。此外,对于可能引发数据竞争的共享资源,应使用互斥锁或信号量等机制来保护。 10. 示例应用: 例如,在实时控制系统中,...
- 在中断处理过程中,CPU处于中断上下文,这意味着不能调度其他进程,也不能执行阻塞操作。 - 因此,中断处理程序必须保持轻量级,快速完成任务。 7. **中断异常与错误处理** - 如果在中断处理过程中出现错误,...
中断是实时系统中不可或缺的一部分,它允许处理器在执行正常任务的同时响应外部事件。 C6748 DSP的中断控制模块提供四种类型的中断信号: 1. 一个可屏蔽的硬件异常(EXCEP) 2. 十二个可屏蔽硬件中断(INT4到INT15...