Java并发队列ConcurrentLinkedQueue抢票示例

本文通过实例解析了如何使用Java的ConcurrentLinkedQueue实现并发抢票,展示了其在避免数据竞争上的优势,并介绍了如何配合CountDownLatch确保打印总票数在所有线程执行完毕后进行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ConcurrentLinkedQueue并发抢票示例

在学习java并发的时候,在网上看了几个靠加锁方法块的方法来演示抢票的示例,运行起来还是要起并发冲突。后来看到一个用ConcurrentLinkedQueue(并发链接队列)来演示抢票的demo不错。然后我想在main最后末尾的时候打印各个并发线程实际抢票的总数,却始终看不到该显示出来的打印行。原来是main线程也参与了并发,打印行随机在中间位置。为了解决这个问题,可以使用CountDownLatch(倒计锁),等并发抢票线程都结束后,再接着运行main线程中后面的打印语句。
ConcurrentLinkedQueue的语义描述,可参考一下:

  • A {@code ConcurrentLinkedQueue} is an appropriate choice when
  • many threads will share access to a common collection.
  • Like most other concurrent collection implementations, this class
  • does not permit the use of {@code null} elements.

java示例demo

public class SellTicketQueue {
    static Queue<String> tickets = new ConcurrentLinkedQueue<>();//1.初始化并发队列容器
    static {
        for (int i = 1; i <= 1000; i++) tickets.add("第" + i + "张票");//2.往容器中放1000张票
    }
    static  HashMap<String, Integer> map = new HashMap<>();
    final static CountDownLatch countDownLatch = new CountDownLatch(3);

    public static void main(String[] args) {
        for (int i = 0; i < 4; i++) {  //3.开启多个线程抢票
            new Thread(() -> {
                while (true) {
                    String ticket = tickets.poll();  //4.一张张票出队列
                    if (ticket == null) break;
                    else System.out.println(Thread.currentThread().getName() + "销售--" + ticket);
                    Integer num = map.computeIfAbsent(Thread.currentThread().getName(), k -> 0);
                    num++;
                    map.put(Thread.currentThread().getName(), num);
                }
                countDownLatch.countDown();
            }).start();
        }

        //5.以下代码实现在抢票线程完毕后,再打印各小计票数(保证打印在最末尾)
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (Map.Entry<String, Integer> m : map.entrySet()) {
            System.out.println(m.getKey() + " 总数 : " + m.getValue());
        }
        System.out.println("main thread is over ");
    }
}

运行结果:这样看起来汇总小计直观一些。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值