JUC基础-C5-Callable接口&JUC辅助类

1 Callable接口

Runnable接口和Callable接口都可以用于创建线程,但二者有功能上的差异

1,Runnable接口无返回值,Callable接口有返回值
2,Runnable接口无法抛异常,Callable接口可以抛异常

使用Callable接口创建线程可以使用FutureTask
FutureTask用于计算"未来任务" 不影响主线程的情况下开启一个线程计算结果
	public static void main(String[] args) throws ExecutionException, InterruptedException {

        FutureTask futureTask1 = new FutureTask(new Callable() {
            @Override
            public Integer call() throws Exception {
                System.out.println(Thread.currentThread().getName() + " call");
                return 100;
            }
        });
        Thread a = new Thread(futureTask1, "a");
        a.start();

        // isDone() 判断FutureTask启动的线程是否执行结束
        while (!futureTask1.isDone()) {
            System.out.println("wait");
        }
        
        // get() 用于获取FutureTask返回的结果
        System.out.println(futureTask1.get());
        System.out.println(futureTask1.get());
    }

2 JUC中的辅助类

2.1 CountDownLatch 减少计数

CountDownLatch类可以设置一个计数器 然后通过countDown()方法来执行减1的操作

CountDownLatch主要有两个方法 当一个或多个线程调用await()时 这些线程会阻塞
其它线程调用countDown()时会将计数器减1 调用countDown()方法的线程不会阻塞
当计数器的值为0时 因await()阻塞的线程会被唤醒 继续执行

使用场景如: 教室离开6个同学后再锁门
	public static void main(String[] args) throws InterruptedException {

        CountDownLatch countDownLatch = new CountDownLatch(6);

        for (int i = 1; i <= 6; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " 同学离开");
                    countDownLatch.countDown();
                }
            }, String.valueOf(i)).start();
        }

        // 主线程等待计数器为0才能继续执行
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() +  " 6个同学离开后,锁门");

    }

2.2 CyclicBarrier 循环栅栏

CyclicBarrier循环阻塞 其构造需要的参数即"目标障碍数""目标任务"
每执行一次await()一次 障碍数加1
如果达到了目标障碍数 才会执行目标任务
没有达到目标障碍数则会一直等待

使用场景如: 凑够5个人一起玩游戏
public static void main(String[] args) throws InterruptedException {

        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                System.out.println("凑够5人一起玩游戏");
            }
        });

        for (int i = 1; i <= 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {

                    try {
                        System.out.println(Thread.currentThread().getName() + " 号报到");
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            }, String.valueOf(i)).start();
        }

    }

2.3 Semaphore 信号灯

Semaphore构造的第一个参数是"最大信号量" 第二个是"公平/非公平" 默认非公平
每个信号量可以看作一个"许可证" 拿到许可的线程才能执行
使用acquire()可以获取许可 通过release()释放许可

使用场景如: 6辆车抢3个车位
	public static void main(String[] args) throws InterruptedException {
        Semaphore semaphore = new Semaphore(3);

        for (int i = 1; i <= 6; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName() + " 抢到了车位");

                        TimeUnit.SECONDS.sleep(new Random().nextInt(5));
                        System.out.println(Thread.currentThread().getName() + " 离开了车位");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        semaphore.release();
                    }

                }
            }, String.valueOf(i)).start();
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值