概要分类
public interface BlockingQueue<E> extends Queue<E> {
//这两个一对 add不能立即被执行就会抛异常 remove一般返回true和false代表是否执行成功
boolean add(E var1);
boolean remove(Object var1);
//这个直接会返回一个结果
boolean offer(E var1);
E poll(); 【这个是父类Queue里面的方法】
//这两个不能立即被执行就会被阻塞
void put(E var1) throws InterruptedException;
E take() throws InterruptedException;
//这个在不能被执行 超时后会返回一个特殊值
boolean offer(E var1, long var2, TimeUnit var4) throws InterruptedException;
E poll(long var1, TimeUnit var3) throws InterruptedException;
int remainingCapacity();
boolean contains(Object var1);
int drainTo(Collection<? super E> var1);
int drainTo(Collection<? super E> var1, int var2);
}
- Throws Exception 类型的插入和取出在不能立即被执行的时候就会抛出异常。
- Special Value 类型的插入和取出在不能被立即执行的情况下会返回一个特殊的值(true 或者 false)
- Blocked 类型的插入和取出操作在不能被立即执行的时候会阻塞线程直到可以操作的时候会被其他线程唤醒
- Timed out 类型的插入和取出操作在不能立即执行的时候会被阻塞一定的时候,如果在指定的时间内没有被执行,那么会返回一个特殊值
SynchronousQueue
阻塞代码
synchronousQueue是一个特殊的queue,本身不存储任何元素
take和put
demo1-take唤醒block的put demo2-put唤醒block的take
SynchronousQueue<String> queue = new SynchronousQueue<String>();
new Thread(()->{
try {
Thread.yield();
//取走内容-打破block-1
String content = queue.take();
System.out.println("step2-成功取值"+content);
content = queue.take();
System.out.println("step4-成功取值"+content);
} catch (InterruptedException e) {
//一般阻塞方法都会响应中断
}
}).start();
System.out.println("step1-put1 block1");
queue.put("put1 block1被打破");
Thread.yield();
System.out.println("step3-put2 block2");
queue.put("put2 block2被打破");
打印结果
step1-put1 block1
step2-成功取值put1 block1被打破
step3-put2 block2
step4-成功取值put2 block2被打破
SynchronousQueue<String> queue = new SynchronousQueue<String>();
new Thread(()->{
try {
System.out.println("step1-拿不到血汗钱 把自己挂着");
String content = queue.take();
System.out.println(String.format("追回血汗钱%s 回老家过年", content) );
} catch (InterruptedException e) {
//一般阻塞方法都会响应中断
}
}).start();
Thread.sleep(88);
System.out.println("step2-老板来送钱了");
queue.put("100万");
System.out.println("发完工资 安心回家");
step1-拿不到血汗钱 把自己挂着
step2-老板来送钱了
发完工资 安心回家
追回血汗钱100万 回老家过年
add和remove
SynchronousQueue是一个特殊的queue没有容量 所以add和remove没啥意义。
这个方法我们看ArrayBlockingQueue
offer和poll
这个是非阻塞的,直接返回执行的结果。logback的异步打印appender里面有个配置 如果是neverBlock=true,就会使用offer这个方法。
newCacheThreadPool里面就是用SynchronousQueue的offer永远返回false,所以不停的new新线程
SynchronousQueue的源码解析