JUC 常用知识点 1

三个并发的常用辅助类:

1、CountDownLatch

在这里插入图片描述
可以当做类似一个倒计时计数器来记,一个实例:

老师要等教室里的6个学生都走了才能关门

 // 倒计时计数器
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
	new Thread(()->{
		System.out.println("第"+Thread.currentThread().getName()+"个学生Go out");
		countDownLatch.countDown(); // 减一操作
	},String.valueOf(i)).start();
}
countDownLatch.await(); // 等待计数器为0再向下执行
System.out.println("关门");

2、CyclicBarrier

在这里插入图片描述
可以当做一个加法计数器来记,一个实例:

当集齐七科龙珠,就可以召唤神龙

CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
            System.out.println("召唤神龙成功!");
        });
for (int i = 1; i <= 7; i++) {
	final int temp = i; // 解决作用域的问题(lambda表达式里不能直接拿到i)
	new Thread(()->{
		System.out.println(Thread.currentThread().getName()+"收集了第"+temp+"颗龙珠");
		try {
			cyclicBarrier.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
},String.valueOf(i)).start();}

3、Semaphore

在这里插入图片描述
信号量的辅助类,可以当做限流的使用来记(多个线程使用一个共享资源互斥的使用),实例:

抢车位,3个车位,有6辆车来停,保证有序停车

public class Test3 {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); // 3个车位
        for (int i = 1; i <= 6; i++) {
            final int temp = i; // 解决作用域的问题(lambda表达式里不能直接拿到i)
            new Thread(()->{
                try {
                    semaphore.acquire(); // 得到停车位
                    System.out.println(Thread.currentThread().getName()+"抢到车位");
                    TimeUnit.SECONDS.sleep(2); // 停2秒车
                    System.out.println(Thread.currentThread().getName()+"离开车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release(); // 释放
                }
            },String.valueOf(i)).start();
        }
    }
}

Semaphore的两个主要方法:

semaphore.acquire():获得资源,如果到达峰值,等待至被释放为止;
semaphore.release():将当前的信号量释放,然后唤醒等待的线程;


ReadWriteLock

在这里插入图片描述
读写锁,更加细粒度的操作,它的写是只允许一条线程去写,而读是允许所有线程都可去读。实例:

5条线程去写入,5条线程去读取,确保写入操作不会被其他线程插队

public class Test1 {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        for (int i = 1; i <= 5; i++) { // 只做写入操作
            final int temp = i;
            new Thread(()->{
                myCache.put(temp+"",temp+"");
            },String.valueOf(i)).start();
        }
        for (int i = 1; i <= 5; i++) { // 只做读取操作
            final int temp = i;
            new Thread(()->{
                myCache.get(temp+"");
            },String.valueOf(i)).start();
        }
    }
}
/* 自定义缓存 */
class MyCache {
    private volatile Map<String,Object> map = new HashMap<>();
    // 读写锁,更加细粒度的操作
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    // 存(写入操作,只有一条线程能写)
    public void put(String key,Object value){
        readWriteLock.writeLock().lock(); // 上锁
        try {
            System.out.println(Thread.currentThread().getName()+"写入"+key);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"写入OK");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock(); // 解锁
        }

    }
    // 取(读取操作,所有线程都能读)
    public void get(String key){
        readWriteLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"读取"+key);
            Object o = map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取OK");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }
    }
}

BlockQueue

在这里插入图片描述
阻塞队列的四组API:
在这里插入图片描述
超时等待里的参数详情:

offer(value,时间数,时间类型)
poll(时间数,时间类型)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值