Java cung cấp cơ chế đồng bộ hóa đa luồng mạnh mẽ thông qua CountDownLatch, cho phép luồng chính chờ đợi tất cả các luồng con hoàn thành nhiệm vụ trước khi tiếp tục. Cơ chế này rất hữu ích trong các tình huống xử lý dữ liệu song song, đảm bảo tính toàn vẹn và đồng bộ của kết quả.
- Áp dụng đa luồng trong vòng lặp for, luồng chính và các luồng con không có thứ tự ưu tiên ``` public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 5; i++) { ThreadUtil.execAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Luồng " + Thread.currentThread().getName() + " đã hoàn thành"); }); System.out.println("Luồng thứ " + i); } System.out.println("Hoàn thành"); }
Kết quả thực hiện:
2. Áp dụng đa luồng trong vòng lặp for, luồng chính chờ đợi tất cả các luồng con hoàn thành trước khi tiếp tục
public static void main(String[] args) throws InterruptedException {
// Khởi tạo bộ đếm số luồng
CountDownLatch countDownLatch = ThreadUtil.newCountDownLatch(5);
for (int i = 0; i < 5; i++) {
ThreadUtil.execute(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Luồng " + Thread.currentThread().getName() + " đã hoàn thành");
// Giảm bộ đếm
countDownLatch.countDown();
});
System.out.println("Luồng thứ " + i);
}
// Kích hoạt luồng chính sau khi tất cả luồng con hoàn thành
countDownLatch.await();
System.out.println("Hoàn thành");
}
Kết quả thực hiện:
3. Áp dụng đa luồng trong vòng lặp for, luồng chính chờ đợi tất cả các luồng con hoàn thành trước khi tiếp tục
public static void main(String[] args) throws InterruptedException {
// Số lượng luồng
int N = 10;
// Khởi tạo bộ đếm ngược với N số lượng đếm
CountDownLatch countDownLatch = new CountDownLatch(N);
for (int i = 0; i < N; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
System.out.println("Luồng con " + Thread.currentThread().getName() + " kết thúc nghỉ");
} catch (Exception e) {
e.printStackTrace();
} finally {
// Giảm đếm
countDownLatch.countDown();
}
}
}).start();
}
// Chặn luồng chính, đợi khi đếm về 0 thì thực thi tiếp
countDownLatch.await();
System.out.println("Kết thúc");
}
Kết quả thực hiện:
4 . Xử lý 1000 dữ liệu bằng 10 luồng trong Java
public static void main(String[] args) throws Exception {
List<Integer> danhSachId = new ArrayList<>();
for (int i = 1; i <= 1000; i++) {
danhSachId.add(i);
}
int soLuongLuong = 10;
ExecutorService dichVuLuong = Executors.newFixedThreadPool(soLuongLuong);
CountDownLatch boDem = new CountDownLatch(soLuongLuong);
int kichThuocMoiPhan = danhSachId.size() / soLuongLuong;
// Định nghĩa bộ chứa kết quả - sử dụng bộ an toàn luồng trong môi trường đa luồng
List<Integer> danhSachKetQua = Collections.synchronizedList(new ArrayList());
for (int i = 0; i < soLuongLuong; i++) {
XuLyDaLuong luong = new XuLyDaLuong();
luong.setDanhSachId(danhSachId.subList(i * kichThuocMoiPhan, (i + 1) * kichThuocMoiPhan));
luong.setBoDem(boDem);
luong.setDanhSachKetQua(danhSachKetQua);
dichVuLuong.submit(luong);
}
boDem.await();
dichVuLuong.shutdown();
// Kiểm tra kết quả
System.out.println(danhSachKetQua.size());
System.out.println(danhSachKetQua.stream().sorted().collect(Collectors.toList()));
}
}
class XuLyDaLuong extends Thread { private List<Integer> danhSachId;
private CountDownLatch boDem;
private List<Integer> ketQua;
public void setDanhSachKetQua(List<Integer> ketQua) {
this.ketQua = ketQua;
}
public void setDanhSachId(List<Integer> danhSachId) {
this.danhSachId = danhSachId;
}
public void setBoDem(CountDownLatch boDem) {
this.boDem = boDem;
}
@Override
public void run() {
try {
// Xử lý dữ liệu
for (Integer so : danhSachId) {
if (so % 2 == 0) {
ketQua.add(so);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (boDem != null) {
boDem.countDown();
}
}
}
Kết quả thực hiện: