多线程的使用
举个例子:小明想做一顿饭,需要烧壶开水,洗菜,蒸米三个步骤。现在小米是先洗菜,洗完菜才去烧水,烧完水才去蒸米。一共花费洗菜的时间加烧水的时间加蒸米的时间。
上面就是所谓的串行工作方式,一个步骤完成在去干另一个步骤,比较费时。
```java
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
xiCai();
shaoShui();
zhengMi();
System.out.println("完成洗菜,烧水,蒸饭 花费时间:" + ((System.currentTimeMillis() - start) / 1000) + "s");
}
//洗菜
private static void xiCai() throws InterruptedException {
Thread.sleep(3000);
System.out.println("洗菜(3s)...");
}
//蒸米
private static void zhengMi() throws InterruptedException {
Thread.sleep(10000);
System.out.println("蒸米(10s)...");
}
//烧水
private static void shaoShui() throws InterruptedException {
Thread.sleep(5000);
System.out.println("烧水(5s)...");
}
```
- 上面测试下来大概花费时间:
洗菜(3s)... 烧水(5s)... 蒸米(10s)... 完成洗菜,烧水,蒸饭 花费时间:18s
后来,小明想了想,我烧水的时候也能洗菜,还能蒸米,反正是锅在干活,这样的话我岂不是节约很多时间,最后,饭蒸熟了,我菜也洗了,水也烧了。于是乎......
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
//来一个计数器,每个线程执行完后主线程才可以执行
CountDownLatch downLatch = new CountDownLatch(3);
new Thread(() -> {
try {
xiCai();
} catch (InterruptedException e) {
e.printStackTrace();
}
//洗菜完了计数器会减一
downLatch.countDown();
}).start();
new Thread(() -> {
try {
shaoShui();
} catch (InterruptedException e) {
e.printStackTrace();
}
downLatch.countDown();
}).start();
new Thread(() -> {
try {
zhengMi();
} catch (InterruptedException e) {
e.printStackTrace();
}
downLatch.countDown();
}).start();
//等待所有工作完成后,走下一步
downLatch.await();
System.out.println("完成洗菜,烧水,蒸饭 花费时间:" + ((System.currentTimeMillis() - start) / 1000) + "s");
}
- 上面测试下来大概花费时间:
洗菜(3s)... 烧水(5s)... 蒸米(10s)... 完成洗菜,烧水,蒸饭 花费时间:10s
CountDownLatch:
- 这个类使一个线程等待其他线程各自执行完毕后再执行
- 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
基本使用方法:
- 来一个计数器,每个线程执行完后主线程才可以执行
CountDownLatch downLatch = new CountDownLatch(3);
- 当前线程完了计数器减一
downLatch.countDown();
- 等待所有计数器管理的线程执行完
downLatch.await();