https://blog.csdn.net/AdminC/article/details/83929452
import java.util.Vector;
public class Test {
public static void main(String[] args) throws InterruptedException {
/*
Vector集合: JDK1.0 底层也是数组 是最早期的同步集合 也就意味着是单线程 效率低
实现了list接口所以可以使用list的所有方法
特有方法:
void addElement(E obj) 将指定的组件添加到此向量的末尾,将其大小增加 1
Enumeration<E> elements() 返回此向量的组件的枚举(早期的迭代器)。
*/
Vector<Thread> vector = new Vector<>();
for (int i = 0; i < 5; i++) {
Thread childThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程被执行");
}
});
vector.add(childThread);
childThread.start();
}
for (Thread thread : vector) {
// void join() 等待该线程终止
thread.join();
}
System.out.println("主线程被执行");
}
}
1.CountDownLatch的概念: extends Object
CountDownLatch是一个同步工具类,用来协调多个线程之间的同步
或者说起到线程之间的通信(而不是互斥的作用)
CountDownLatch能够使一个线程在等待另一些线程完成自己任务后,
再继续执行.使用一个计数器进行实现,计数器初始值为线程的总数量(包括主线程).
当每一个线程完成自己任务后,计数器的值减一.当计数器的值为0时,表示所有线程执行完成,
然后在CountDownLatch上等待的线程可以恢复执行任务.
2.CountDownLatch的典型用法:
典型用法1:
某一个线程开始运行前等待n个线程执行完毕.将CountDownLatch的计数器初始化
new CountDownLatch(n),每当一个线程完成任务后,计数器的值就会减一 CountDownLatch.countDown(),当计数器的值为0时,在CountDownLatch上await()的线程就会被唤醒.
应用场景:启动一个服务时,主线程需要等待多个组件加载完毕之后再继续执行.
典型用法2:实现多个线程开始执行任务的最大并行性.这里时并行,不是并发,
强调的是多个线程在某一时刻同时开始执行.类似于赛跑,将多个线程放到七点,等待发令枪,然后同时执行.
做法是初始化一个共享的CountDownLatch(1),将其计数器初始化为1.多个线程开始执行任务前首先CountDownLatch.await().当主线程调用countDown()时,计数器变为0,多个线程同时被唤醒.
3.CountDownLatch的不足:
CountDownLatch是一次性的,计数器的值只能在构造方法中初始化一次,之后没有任何机制能够再次对其设置值,
当CountDownLatch使用完毕后,不能再次被调用.
public static void main(String[] args) throws InterruptedException {
//创建CountDownLatch并初始化为5
CountDownLatch latch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
Thread childthread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程开始执行");
//计数器递减,为0时释放所有线程
latch.countDown();
}
});
childthread.start();
}
//设置主线程等待
latch.await();
System.out.println("主线程开始执行");
}