栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

文章目录
  • 1 Callable接口
  • 2 JUC中的辅助类
    • 2.1 CountDownLatch 减少计数
    • 2.2 CyclicBarrier 循环栅栏
    • 2.3 Semaphore 信号灯

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();
        }

    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/343747.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号