1、测试下面结果按理说应该为1000000,但是因为并发导致结果错误。
package demo;
import java.util.concurrent.CountDownLatch;
public class TestCountDownLatch {
private static int N = 1000; // 线程数
private static int m = 0;
public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(N);// 实例化一个倒计数器,N指定计数个数
for (int i = 0; i < N; i++) {
new Thread(() -> {
try {
// System.out.println(Thread.currentThread().getName() + "启动@" + System.currentTimeMillis());
for (int j = 0; j < 1000; j++) {
m++;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
countDownLatch.countDown(); // 计数减一
}
}).start();
}
countDownLatch.await();// 等待,当计数减到0时,所有线程并行执行
System.out.println(m); // 结果应该1000000
}
}
2、上面的问题加锁解决。
等待所有子线程结束,主线程再执行测试。
package demo;
import java.util.concurrent.CountDownLatch;
public class TestCountDownLatch {
private static int N = 1000; // 线程数
private static int m = 0;
public static void main(String[] args) throws Exception {
Object o = new Object();
CountDownLatch countDownLatch = new CountDownLatch(N);// 实例化一个倒计数器,N指定计数个数
for (int i = 0; i < N; i++) {
new Thread(() -> {
try {
// System.out.println(Thread.currentThread().getName() + "启动@" + System.currentTimeMillis());
for (int j = 0; j < 1000; j++) {
synchronized (o) {// 普通方法上锁为this,静态static方法上锁为类名.class
m++;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
countDownLatch.countDown(); // 计数减一
}
}).start();
}
countDownLatch.await();// 等待,当计数减到0时,所有线程并行执行
System.out.println(m); // 结果应该1000000
}
}
3、等待所有线程加载完,同时并发执行某个代码块。
package demo.teststatic;
import java.util.concurrent.CountDownLatch;
public class Test2 {
private static int N = 10000; // 线程数
private static int m = 0;
public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(N);// 实例化一个倒计数器,N指定计数个数
for (int i = 0; i < N; i++) {
new Thread(() -> {
try {
countDownLatch.countDown(); // 计数减一
System.out.println(m++);
countDownLatch.await();// 等待,当计数减到0时,所有线程并行执行
System.out.println("开始");
for (int j = 0; j < 10000; j++) {
//执行代码块
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}).start();
}
}
}