大白话理解,快速拿下JUC(四)

1、创建线程的几种方式

        a、继承Thread

        b、实现Runnable接口

        c、实现Callable接口

        d、线程池

2、Runnable和Callable的不同

        a、Runnable没有返回值,Callable有返回值

        b、Runnable不会抛出异常,Callable在返回结果计算错误时候抛出异常

        c、实现方式名称不同,Runnable是run方法,Callable是call方法

3、FutureTask

        FutureTask是Runnable的实现类,是未来任务,他具备比Runnable更强大的功能,可以使用FutureTask来实现Callable的创建,以下是简单代码实现        

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class callableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //实现Runnable
        new Thread(new MyThread01(),"A").start();
        //实现Callable
        FutureTask<Integer> task=new FutureTask<>(new MyThread02());
        new Thread(task,"A").start();
        System.out.println(task.get());
        //因为Callable是函数式接口,所以可使用lamda表达式完成匿名函数方式直接返回结果
        FutureTask<Integer> task1=new FutureTask<>(()->{
            System.out.println(Thread.currentThread().getName()+"进来了");
            return 2;
        });
        new Thread(task1,"B").start();
        while (!task1.isDone()){
            System.out.println("还在计算中....");
        }
        System.out.println(task1.get());
        new Thread(task1,"C").start();
        System.out.println(task1.get());
    }
}
class MyThread01 implements Runnable{

    @Override
    public void run() {
        System.out.println("Runnable线程");
    }
}

class MyThread02 implements Callable {
    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName()+"进来了");
        return 1;
    }
}

 下图是运行结果,可见,未来任务是只需要汇总一次的,线程B去执行过一次,打印"B进来了“,得到了返回值2之后,线程C再去执行直接得到结果2

4、JUC辅助类之CountDownLatch

        一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。举例:比如班里有6个同学和一个班长,班长需要等6个同学都走了之后才能锁门离开,那么班长的角色就是CountDownLatch的意思,此工具类叫减少计数

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch=new CountDownLatch(6);
        for (int i = 1; i <=6 ; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+" 同学离开了");
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println("班长离开了");
    }
}

5、JUC辅助类之CyclicBarrier

        一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

        以上解释可以理解为,多个线程都完成后,可以触发的方法,比如以下代码,收集完七颗龙珠后,可以召唤神龙,此工具类叫循环栅栏

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    private static final Integer number=7;
    public static void main(String[] args) {
        CyclicBarrier barrier=new CyclicBarrier(number,()->{
            System.out.println("集齐七颗龙珠,即将召唤神龙!");
        });
        for (int i = 1; i <=7 ; i++) {
            new Thread(()->{
                try {
                    System.out.println(Thread.currentThread().getName()+"星龙珠被收集了");
                    barrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

6、JUC辅助类之Semaphore

        一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。

        以上解释可以理解为,线程间可以抢占有限的资源,有某一个线程完成后可以由其他线程再次竞争,比如以下代码案例,有6个汽车,3个停车位,第一次可以停满3个车为,三个车等待停车,由其中一个车离开之后,其余的3个车抢占那个车位,此工具类叫信号灯

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

//6辆车,3个停车位
public class SemaphoreDemo {
    public static void main(String[] args) {
        //3个车位
        Semaphore semaphore=new Semaphore(3);
        for (int i = 1; i <=6 ; i++) {
            new Thread(()->{
                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、付费专栏及课程。

余额充值