锁测试与超时
java.util.concurrent.locks.Lock#tryLock方法试图申请一个锁,在成功获得锁后返回true,否则,立即返回false,而且线程可以立即离开去做其他事。
也可以使用超时参数。
lock方法不能被中断,而调用带有超时参数的tryLock,如果线程在等待期间被中断,将抛出InterruptedException异常。
也可以使用lockInterruptibly方法。它相当于一个超时设为无线的tryLock方法。
在等待时,也可以设置超时:
java.util.concurrent.locks.Condition#await
阻塞队列
之前介绍了java并发程序设计基础的底层构建模块。然而,对于实际编程来说,应该尽可能远离底层结构,不用重复造轮子。
当试图向队列添加元素而队列已满,或是想从队列移出元素而队列为空的适合,阻塞队列导致线程阻塞。在协调多个线程之间的合作时,阻塞队列是一个有用的工具。
| 方法 | 正常动作 | 特殊情况下的动作 |
|---|---|---|
| add | 添加一个元素 | 如果队列满,抛出IllegalStateException |
| element | 返回队列头元素 | 如果队列为空,抛出NoSuchElementException |
| offer | 添加一个元素并返回true | 如果队列满,返回false |
| peek | 返回队列的头元素 | 如果队列空,返回null |
| poll | 移出并返回队列头元素 | 如果队列空,返回null |
| put | 添加一个元素 | 如果队列满,阻塞 |
| remove | 移出并返回头元素 | 如果队列空,则抛出NoSuchElementException |
| take | 移出并返回头元素 | 如果队列空,阻塞 |
从响应来看,当用于线程管理时,pull和take有用。同时要注意,返回null的几个方法其实暗含了不能塞入null对象哦
常用的阻塞队列
-
默认情况下,LinkedBlockingQueue的容量时没有上边界,但是,也可以选择指定最大容量。
-
LinkedBlockingDeque是一个双端版本。
-
ArrayBlockingQueue在构造时需要指定容量,并且有一个可选的参数来指定是否需要公平性,优先最长等待线程。当然这是牺牲了性能的,所以只有特别需要时会用到。
-
PriorityBlockingQueue是一个带优先级的队列,没有容量上限。
-
Delayed接口提供了对象的残留延迟。对象只有在延迟用完的情况下才能从DelayQueue移出。
-
TransferQueue接口,允许生产者线程等待,直到消费者准备就绪可以接收一个元素。