多线程六阻塞队列
什么是阻塞队列
写入队列时:如果队列满了,就必须阻塞等待
从队列取时:如果队列是空的,就必须阻塞
BlockingQueue
怎么使用阻塞队列
操作 | 抛出异常 | 不会抛出异常有返回值 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加 | add() | offer() | put() | offer(Object,int,TimeUtil) |
移除 | remove() | poll() | take() | poll(int,TimeUtil) |
判断队列头 | element() | peek() |
BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<>(2);
/*抛出异常*/
//System.out.println(blockingQueue.add("a"));//true
//System.out.println(blockingQueue.add("b"));//true
//System.out.println(blockingQueue.element());//"a"
//System.out.println(blockingQueue.add("c"));//异常:Exception in thread "main" java.lang.IllegalStateException:Queue full
//System.out.println(blockingQueue.remove());//"a"
//System.out.println(blockingQueue.remove());//"b"
//System.out.println(blockingQueue.element());//异常:Exception in thread "main" java.util.NoSuchElementException
//System.out.println(blockingQueue.remove());//异常:Exception in thread "main" java.util.NoSuchElementException
/*不抛出异常*/
//System.out.println(blockingQueue.offer("a"));//true
//System.out.println(blockingQueue.offer("b"));//true
//System.out.println(blockingQueue.peek());//"a"
//System.out.println(blockingQueue.offer("c"));//false 不抛出异常
//System.out.println(blockingQueue.peek());//"a"
//System.out.println(blockingQueue.poll());//"a"
//System.out.println(blockingQueue.poll());//"b"
//System.out.println(blockingQueue.poll());//null
//System.out.println(blockingQueue.peek());//null
/*等待,一直阻塞*/
//blockingQueue.put("a");
//blockingQueue.put("b");
//blockingQueue.put("c");//阻塞住下面不执行
//System.out.println(blockingQueue.take());//"a"
//System.out.println(blockingQueue.take());//"b"
//System.out.println(blockingQueue.take());//一直等待
/*等待,超时退出*/
System.out.println(blockingQueue.offer("a"));//true
System.out.println(blockingQueue.offer("b"));//true
System.out.println(blockingQueue.offer("a",1, TimeUnit.SECONDS));//一秒后返回false并且不插入
System.out.println(blockingQueue.poll());//"a"
System.out.println(blockingQueue.poll());//"b"
System.out.println(blockingQueue.poll(1,TimeUnit.SECONDS));//一秒后返回null
同步队列
//SynchronousQueue不存储元素,put了一个元素,必须先take取出来,否则不能再put
BlockingQueue<String> blockingQueue=new SynchronousQueue<>();
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+":put:1");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName()+":put:2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName()+":put:3");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"putThread").start();
new Thread(()->{
try {
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()+":take:"+blockingQueue.take());
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()+":take:"+blockingQueue.take());
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()+":take:"+blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"takeThread").start();
}
putThread:put:1
takeThread:take:1
putThread:put:2
takeThread:take:2
putThread:put:3
takeThread:take:3