LinkedBlockingQueue的api


LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE

//生产者消费者模式: ArrayBlockingQueue有界队列
public class BlockingQueueExample {

	public static void main(String[] args) {
		BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);

		Producer producer = new Producer(queue);
		Consumer consumer = new Consumer(queue);

		new Thread(() -> producer.m()).start();
		new Thread(() -> consumer.m()).start();

		try {
			TimeUnit.SECONDS.sleep(4);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class Producer {
	protected BlockingQueue<String> queue = null;

	public Producer(BlockingQueue<String> queue) {
		this.queue = queue;
	}

	public void m() {
		try {
			boolean b1 = queue.offer("1");
			// Thread.sleep(1000);
			boolean b2 = queue.offer("11");
			Thread.sleep(1000);
			boolean b3 = queue.offer("2");
			Thread.sleep(1000);
			boolean b4 = queue.offer("3");
			System.out.println(b1 + " " + b2 + " " + b3 + " " + b4 + " ");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class Consumer {
	protected BlockingQueue<?> queue = null;

	public Consumer(BlockingQueue<?> queue) {
		this.queue = queue;
	}

	public void m() {
		try {
			System.out.println(queue.take() + "--1");
			System.out.println(queue.take() + "--2");
			System.out.println(queue.take() + "--3");
			System.out.println(queue.take() + "--4");// 若队列中没有数据了,会阻塞
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

offer方法不会阻塞,如果不能插入队列直接返回,有可能造成数据丢失。比如上面的例子,队列长度为1,11是会丢失掉,而put方法会阻塞,等待消费完有空位时,唤醒put线程。
相同的道理:获取元素,take方法是阻塞的,poll方法不是阻塞的。

peek()+remove()与 poll()功能类似:
public void doLoan() {  
    logger.debug("NoticeTask start");  
    while (NoticeJobQueue.NOTICE != null && NoticeJobQueue.NOTICE.size() > 0) {  
        Notice notice = NoticeJobQueue.NOTICE.peek();  
        if (notice != null) {  
            try {  
                noticeService.sendNotice(notice);  
            } catch (Exception e) {  
                logger.error(e.getMessage(), e);  
                e.printStackTrace();  
            } finally {  
                NoticeJobQueue.NOTICE.remove(notice);
            }  
        }  
    }  
}

对比各种queue(并发情景下使用的是最多的就是queue)

LinkedBlockingQueue   阻塞式队列中用put/take来存取,满了去put或者空了再take都会引起阻塞等待,自动实现阻塞是生产者消费者,它是无界队列,可以容纳无限个元素,只要内存可以支撑。但是消费者一直在消费是不会满的
ArrayBlockingQueue     有界队列,装的是一个一个的任务,在线程池里用的比较多,api包括offer,add,peek等等
DelayQueue                  无界队列,装的也是一个一个任务,默认是按添加时间排好顺序的,等待时间最长的排在最前,任务记录了还有多长时间可以被消费,可以用来做定时任务。任务需要实现Delayed接口,而他又是从Comparable接口继承的
LinkedTransferQueue    一般用在实时的消息处理,必须先启动消费者,在调用transfer(),否则就会阻塞

SynchronousQueue       是一个容量为0的特殊的TranferQueue,内部调用的tranfer()来执行,任何一个元素必须立刻交给消费者消费。transfer不会加到队列里,直接交给消费者

CopyOnWrite                实际业务中写的很少,读的特别多的情况使用。

ConcurrentLinkedQueue全是采用的非阻塞算法,里面没有使用任何锁,全是基于CAS操作实现的,这样来保证元素的一致性。CAS操作可以说是JAVA并发框架的基础,整个框架的设计都是基于CAS操作的。

JAVA并发编程学习笔记之CAS操作



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值