Sử dụng Đa luồng trong Vòng lặp For với CountDownLatch

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ả.

  1. Á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:

Thẻ: Java CountDownLatch Đa luồng ExecutorService

Đăng vào ngày 1 tháng 10 lúc 10:26