跟南桑学JUC第四节课(Callable)

14.走进Callable

image-20210412215017115

  1. 可以有返回值
  2. 可以抛出异常
  3. 方法不同,call()

Runnable的Api文档

image-20210412215902849

FutureTask的Api文档

image-20210412220923181

image-20210412220818395

public class CallableTest {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        //Callable  ---   Runnable  中间转换(适配类)
        FutureTask<String> futureTask = new FutureTask<>(thread);
        //结果会被缓存,提高效率
        new Thread(futureTask, "A").start();
        new Thread(futureTask, "B").start();

        //获取返回值
        try {
            //这个get方法可能会产生阻塞,把它放到最后
            String s = futureTask.get();
            //或者使用异步通信来处理
            System.out.println(s);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

class MyThread implements Callable<String> {
    @Override
    public String call() {
        System.out.println("call()");
        //可能是耗时的操作
        return "123";
    }
}

输出

call()
123

细节;

  1. 有缓存
  2. 结果可能需要等待,会阻塞!

15.CountDownLatch

image-20210412222203712

减法计数器

public class CountDownLatchDemo {
    public static void main(String[] args) {
        //总数是6 必须要执行的任务的时候再使用
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+" go out");
                // 数量-1
                countDownLatch.countDown();
            }).start();
        }

        try {
            //等待计数器归零,然后再往下执行
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("close door");

    }
}

原理:

countDownLatch.countDown(); //数量-1

countDownLatch.await();//等待计数器归零,然后再往下执行

每次线程调用countDown()数量-1,假设计数器变成0,countDownLatch.await()就会被唤醒,继续执行!

16.CyclicBarrier

image-20210417160935904

加法计算器

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        /**
         * 集齐七颗龙珠,召唤神龙
         */
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, ()->{
            System.out.println("召唤神龙成功!");
        });
        for (int i = 1; i <= 7; i++) {
            final int temp = i;
            new Thread(() -> {
                System.out.println("收集"+temp+"星龙珠");
                try {
                    //阻塞
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

输出

收集1星龙珠
收集2星龙珠
收集3星龙珠
收集5星龙珠
收集4星龙珠
收集6星龙珠
收集7星龙珠
召唤神龙成功!

17.Semaphore

Semaphore:信号量

image-20210417162124437

抢车位

5辆车,3个停车位

public class SemaphoreDemo {
    public static void main(String[] args) {
        //3个停车位 限流
        Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                try {
                    //获得
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "获得停车位");
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName() + "离开停车位");
                }
            }, String.valueOf(i)).start();
        }
    }
}

输出

2获得停车位
3获得停车位
1获得停车位
3离开停车位
4获得停车位
2离开停车位
1离开停车位
5获得停车位
4离开停车位
5离开停车位

原理:

semaphore.acquire(); //获得,假设已经满了,等待,等待被释放为止!

semaphore.release();//释放,会将当前的信号量释放,然后唤醒等待线程!

作用:

多个共享资源互斥使用!并发限流,控制最大线程数!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值