并发编程学习笔记5

[b]阻塞的队列和生产者消费者模式[/b]
主要讲述了,jdk5,6提供的各种阻塞队列。
最有意思的是jdk6中提供的双向队列Deque和BlockDeque,这种队列的工作原理很有意思,他们自己有自己的producer,然后一般来说都自己去消费生产的东西,但是如果某个队列已经将自己的消费完了,那么他会从别人的队列末尾取东西然后消费,大大减少竞争的几率。这种模式也叫作“Work Stealing"

[b]阻塞和中断方法[/b]
线程在等待IO结束,获取锁,等待被从Thread.sleep中唤醒,或者等待另一个线程计算结束的时候,都会被阻塞或者暂停。当一个线程阻塞了,他通常会被暂时搁置并处于几种阻塞状态之一(BLOCKED,WAITING,TIMED_WAITING).一个阻塞的操作和一个原始的普通的操作的差别仅仅是阻塞的线程必须等待一个非他控制的事件,然后才能继续完成IO操作,或者锁的获得,或者是计算的完成。当一个外部事件发生之后,线程将被该变成RUNNABLE状态并且重新被调度。比如,当一个线程在等待一个IO结束的时候,他被阻塞了,然后当一个外部事件发生之后,这种阻塞结束,而这个线程继续自己的执行。

如果一个方法抛出InterruptedException,则表明他是一个阻塞方法,更进一步的说,如果他被打断执行,那么他会尽力使自己尽早脱离阻塞。

Thread提供了interrupt方法,用来中断一个线程和查询一个线程是否被中断了。每个线程都有一个boolean属性用来表示其中断状态,当中断一个方法的时候该值将被设置。

Interruption是一个合作的方法。一个线程不能强迫另一个线程停止他所作的事情或者强迫另一个线程作别的东西;当A线程interrupt线程B的时候,A仅仅是向B发送一个请求,请求B在方便的时候中断当前所作的事情。中断最大的用处就是用来取消一个活动。

如果你的代码调用了一个能抛出InterruptionException的方法,那么你的方法也就成为了一个阻塞的方法,那么你必须为中断这种情况作出反应,必须有相应的处理措施。对于library来说,一般有两种选择:
1.继续传递InterruptionException。将该异常传递给他的调用者,由调用着负责处理。
2.恢复中断。有时候,你不能抛出中断异常,比如当你的代码是Runnable的一部分。在这些情况下,你必须捕获中断异常然后调用当前线程的interrupt方法来恢复中断状态,这样调用栈的上层代码将能发现有中断流出。

现在可能更加对中断迷惑了。但是在绝大多数的情况下,以上两种方法都能工作。但是有一件事情你不能作,那就是捕获了中断异常但是却没作任何反应。如果你这么作了,那么调用栈上层代码就没有机会为中断作出反应--线程中断的信息已经丢失了。

[code]
public class TaskRunnable implements Runnable {
BlockingQueue<Task> queue;
...
public void run() {
try {
processTask(queue.take());
} catch (InterruptedException e) {
// restore interrupted status
Thread.currentThread().interrupt();
//将中断信息保留下了,如果没有这些,则中断信息丢失
}
}
}
[/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值