Java线程池实现多窗口卖票,同时使用CountDownLatch实现等待全部线程完成

个人原创,谢谢支持

代码个人编写,实测有效,欢迎转载本文链接。https://blog.csdn.net/u014730287/article/details/103399779

实现原理

启动多线程卖票

使用 ExecutorService executorService = newFixedThreadPool(threadNum); 方法,创建线程池,该创建方法,能够创建固定线程数的线程池。创建线程的几种方法,以后再讲。

创建完成后,使用 executorService.execute(task); 方法,启动线程。

使用内置方法,等待多线程统一结束

  • 1 、等待全部线程结束,需要用到CountDownLatch方法,具体代码为CountDownLatch threadSignal = new CountDownLatch(threadNum); threadNum与启动线程数相对应,不然会造成全部线程未结束,后续代码提取启动、或者一直等待死锁问题。
  • 2、每个线程执行结束后,都必须调用downLatch.countDown(); 方法,不然那线程计数器不减1,程序一直等待。
  • 3、主线程执行** threadSignal.await(120,TimeUnit.SECONDS);** 方法,该方法会等待全部线程结束,然后执行后续代码。又分为有参、无参两种。无参:当线程未执行第二步时,会一直等待,形成死锁;有参:程序会等待相应的时间,超时后自动执行后续代码。程序还在执行,就提示执行下一步了

实现代码

启动多线程类

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import static java.util.concurrent.Executors.*;

/**
 * 多线程测试查看
 * @author fkptxmz
 */
public class WatchThread {

    private void testExecutor(){
        //启动线程数
        int threadNum = 9;
        //初始化CountDownLatch
        CountDownLatch threadSignal = new CountDownLatch(threadNum);
        //初始化线程池
        ExecutorService executorService = newFixedThreadPool(threadNum);
        for (int i = 0; i < threadNum; i++) {
            //创建多线程对象
            Runnable task = new StationSaleTicket(threadSignal);
            // 线程池执行多线程任务
            executorService.execute(task);
        }
        try {
            //等待线程全部执行完成,最大等待时间120秒,
            // 防止线程未调用countDown()方法,使得程序一直等待,造成死锁
            //threadSignal.await(120,TimeUnit.SECONDS);

			//设置超时时间为1秒钟,查看超时时,是否会跳过线程等待,执行后续代码
            threadSignal.await(1,TimeUnit.SECONDS);

            System.out.println("------------>:线程全部结束,可以执行下一步");
        } catch (Exception e) {
            e.printStackTrace();
        }
        executorService.shutdown();
    }
    /**
     * 测试方法
     */
    public static void main(String[] args){
        WatchThread test = new WatchThread();
        test.testExecutor();
    }

}

卖票代码实现


import java.util.UUID;
import java.util.concurrent.CountDownLatch;

/**
 * @author fkptxmz
 */
public class StationSaleTicket implements Runnable {
    private CountDownLatch downLatch;

    StationSaleTicket(CountDownLatch downLatch) {
        this.downLatch = downLatch;
    }

    /**
     * 为了保持票数的一致,票数要静态
     */
    private static int totalTicket = 5000;
    /**
     * 创建一个静态秘钥
     */
    private static final String TICKET_KEY = "ticket";

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "开始...");
        // do something
        while (totalTicket > 0) {
            synchronized (TICKET_KEY) {
                if (totalTicket > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖出了第" + totalTicket + "张票,编号为:" + this.getTicketUuid());
                    totalTicket--;
                } else {
                    System.out.println(Thread.currentThread().getName() + "票卖完了!!!");
                }
            }
            try {
                //线程睡眠
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            //线程睡眠
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 核心处理逻辑
        // 用到成员变量name作为参数
        // 线程结束时计数器减1
        System.out.println(Thread.currentThread().getName() + "结束. 还有" + downLatch.getCount() + " 个线程");
        //必须等核心处理逻辑处理完成后才可以减1
        downLatch.countDown();

    }

    /**
     * 获取UUID
     *
     * @return String
     */
    private String getTicketUuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值