JUC并发包

JUC并发包

CountDownLatch(多等一)

​ CountDownLatch:是java.util.concurrent并发包下的一个工具类,其意思“倒计时门闩”,它允许一个或多个线程一直等待直到其他线程执行完毕才开始执行

简单来讲就是:
多个人等一个信号后继续执行操作:例如5个运动员,等一个发令员的枪响。

不足:
1: CountDownLatch是不能够重用的
根据上面的解析,大家也发现,共享锁加锁的操作并不会增加state的值。CountDownLatch中state一旦变成0就没有提供其他方式增长回去了。
所以CountDownLatch是一次性消耗品,用完就得换新的。这样设计也是比较正常的,对状态的要求比较严格,例如已经开始比赛了你再告诉裁判说,这次再加5个人,比赛都进行一半了,不会考虑再回去的。随意修改约束值会带来很多逻辑上的问题。

2: 如果没有指定失效时间的话会无限等待

代码示例

package com.rj.bd.zy.JUCPackage.countDownLatchs;

import java.util.concurrent.CountDownLatch;

/**
 * @desc	第一题  
 * @author	高增源
 * @time	2021年10月26日
 */
public class Test01 {
	public static void main(String[] args) throws InterruptedException {
		CountDownLatch countDownLatch=new CountDownLatch(10);
		for (int i = 0; i < 10; i++) {
			new Thread(()->{
				System.out.println("选手"+Thread.currentThread().getName()+":开始跑步");
				try {
					Thread.sleep((int)Math.random()*1000);//耗时模拟选手跑步
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("选手"+Thread.currentThread().getName()+":跑到终点");
				countDownLatch.countDown();//让计数器减一
			}).start();
		}
		//等待所有选手跑完
		countDownLatch.await();
		//输出打印比赛结束
		System.out.println("比赛结束");
	}
}

如果有需要多线程重用的时候该怎么办,为此就引出了我们接下来要讲的CyclicBarrier类

CyclicBarrier

​ 翻译成中文就是”循环栅栏/障碍“,可以使一定数量的线程反复地在栅栏位置处汇集。当线程到达栅栏位置时将调用await方法.

​ 这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用。

​ 可重用:

​ 它有reset方法将栅栏重置为初始值

代码示例

package com.rj.bd.zy.JUCPackage.CyclicBarriers;
/**
 * @desc	学生类:模拟去吃饭,人齐再开饭
 * @author	高增源
 * @time	2021年10月26日
 */

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

public class student extends Thread{
	CyclicBarrier cyclicBarrier;
	public student(CyclicBarrier cyclicBarrier) {
		this.cyclicBarrier = cyclicBarrier;
	}

	@Override
	public void run() {
		System.out.println("小伙伴"+Thread.currentThread().getName()+"出发了");
		try {
			Thread.sleep((int)(Math.random()*2000));//耗时操作模拟出发到到达耗时
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("小伙伴"+Thread.currentThread().getName()+"到了");
		try {
			cyclicBarrier.await();//到达之后等待,等所有人到后开饭
		} catch (InterruptedException | BrokenBarrierException e) {
			e.printStackTrace();
		}
		System.out.println("小伙伴"+Thread.currentThread().getName()+"说:人齐了开饭");
	}
}

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

//====================================================================
/**
 * @desc	第一题测试类:测试学生类
 * @author	高增源
 * @time	2021年10月26日
 */
public class Test01 {
	public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
		//设置一个栅栏计数器
		CyclicBarrier cyclicBarrier=new CyclicBarrier(5);
		for (int i = 0; i < 5; i++) {
			new student(cyclicBarrier).start();
		}
	}
}

Semaphore

Semaphore可以用于做流量控制,特别公用资源有限的应用场景,比如数据库连接。

​ 假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发的读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数只有10个,这时我们必须控制只有十个线程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。这个时候,我们就可以使用Semaphore来做流控

类比:新生开学的时候,假如有1000人,河软只有3个门,所以我们只能同时开启3个门迎接新生。

semaphore.acquire();//请求令牌

semaphore.release();//释放令牌

代码示例

package com.rj.bd.zy.JUCPackage.Semaphores.zy1;

import java.util.concurrent.Semaphore;

/**
 * @desc	老师类:今天有20个学生考试了,而老师每次最多只能看3个人的答案
 * @author	高增源
 * @time	2021年10月26日
 */
public class Teacher {
	public static void main(String[] args) {
		//设置最大线程并行数
		Semaphore semaphore=new Semaphore(3);
		for (int i = 0; i < 20; i++) {
			new Student("同学"+i).JiaoZuoYe(semaphore);
		}
	}

}

package com.rj.bd.zy.JUCPackage.Semaphores.zy1;

import java.util.concurrent.Semaphore;


/**
 * @desc	学生类	
 * @author	高增源
 * @time	2021年10月26日
 */
public class Student {
	private String name;

	public Student(String name) {
		this.name = name;
	}
	
	public void JiaoZuoYe(Semaphore semaphore){
		new Thread(()->{
			System.out.println(name+" 交作业等老师批");
			try {
				semaphore.acquire();//请求令牌
				Thread.sleep((int)(Math.random()*1000));//设置随机延时操作,模拟老师批作业耗时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(name+" 老师批完了");
			semaphore.release();//释放令牌
		}).start();
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值