java基础----CountDownLatch、CyclicBarrier
CountDownLatch是juc包里面的一个计数器,用户可以为他设置一个初始值,并调用他的await()方法使当前线程转变为阻塞状态,直到CountDownLatch计数完毕。
Enum是java中的枚举,当程序运行过程中需要根据一定的对应关系去获取一些数据的时候,通过数据库去拿这些数据是非常消耗性能的,因为中间有创建和销毁数据库连接的消耗,因此,可以用枚举来实现这些功能。
下面通过一个例子来理解这两个东西
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
Random rd = new Random();
System.out.println(Thread.currentThread().getName() + "线程开始");
for(int i = 0; i < 6; i++)
{
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "线程开始");
TimeUnit.SECONDS.sleep(rd.nextInt(5));
System.out.println(Thread.currentThread().getName() + "线程结束");
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
},ThreadEnum.getThreadNameByKey(i).getRetMessage()).start();
}
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "线程结束");
}
}
在上述代码中,我们希望main线程在所有子线程都结束后才结束,因此在main线程中加入了countDownLatch.awati()方法,而每个子线程结束的时候,都会让countDownLatch - 1。值得一提的是,在获取线程名的时候,代码里面使用了枚举的方式去获取,ThreadEnum.getThreadNameByKey(i).getRetMessage()。枚举具体的代码如下:
import jdk.nashorn.internal.objects.annotations.Getter;
public enum ThreadEnum {
ONE(0,"a"),
TWO(1,"b"),
THREE(2,"c"),
FOUR(3,"d"),
FIVE(4,"e"),
SIX(5,"f");
private Integer retCode;
private String retMessage;
public Integer getRetCode() {
return retCode;
}
public void setRetCode(Integer retCode) {
this.retCode = retCode;
}
public String getRetMessage() {
return retMessage;
}
public void setRetMessage(String retMessage) {
this.retMessage = retMessage;
}
ThreadEnum(Integer retCode, String retMessage)
{
this.retCode = retCode;
this.retMessage = retMessage;
}
public static ThreadEnum getThreadNameByKey(int index)
{
ThreadEnum[] myArray = ThreadEnum.values();
for(ThreadEnum element : myArray) {
if(index == element.getRetCode())
{
return element;
}
}
return null;
}
}
CyclicBarrier与CountDownLatch不同,如果说CountDownLatch相当于在做一个减法操作的话,那么CyclicBarrier就是在做一个加法操作,CyclicBarrier中会设置一个parties和一个runnabled,parties代表着需要多少个线程进来之后,才会执行runnabled里面的逻辑。而每个线程调用CyclicBarrier中的await方法后,就会进入到CyclicBarrier的计数当中,并切换到阻塞状态,直到指定数量的线程都进来CyclicBarrier后,屏障解除,各线程继续执行,同时运行CyclicBarrier中runnabled中的逻辑。
如下列代码
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
public class CydicBarrierDemo {
public static void main(String[] args) {
Random rd = new Random();
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("终极任务开始");
});
for(int i = 0; i < 7; i ++)
{
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "\t线程启动了");
TimeUnit.SECONDS.sleep(rd.nextInt(5));
System.out.println(Thread.currentThread().getName() + "\t线程变为阻塞状态了");
cyclicBarrier.await();
System.out.println(Thread.currentThread().getName() + "\t线程重新运行了");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},"t"+i).start();
}
}
}