TỔNG QUAN
CẤU TRÚC ĐIỀU KHIỂN
VÒNG LẶP
CHUỖI VÀ MẢNG
COLLECTIONS
THƯ VIỆN QUAN TRỌNG
HƯỚNG ĐỐI TƯỢNG
XỬ LÝ LUỒNG
EXCEPTION
LÀM VIỆC VỚI FILE
THAM KHẢO
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Sử dụng CountDownLatch trong Java

Trong bài trước, các bạn đã được học về cách tạo và sử dụng ThreadPool trong Java. Sang bài này, tôi sẽ hướng dẫn các bạn về CountDownLack của Thread trong Java. Các bạn theo dõi nhé!

1. CountDownLatch

CountDownLatch là một lớp trong Java chuyên dùng để đếm. Tại sao Java lại tạo ra một lớp riêng để đếm trong khi chúng ta hoàn toàn có thể thực hiện việc đếm bằng cách khác? Bởi vì trong lập trình đa luồng, việc đếm này sẽ rất khó và phức tạp, thường khi muốn đếm thì chúng ta phải sử dụng đến đồng bộ phương thức nếu không việc đếm sẽ không chính xác, vì lúc này trong hệ thống các luồng đang được xử lý song song và các biến sẽ được sử dụng một cách không tuần tự lúc đó kết quả đếm sẽ không chính xác và không như chúng ta mong muốn.

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Để hiểu rõ hơn các bạn theo dõi ví dụ sau:

DemoNonCountDownLatch.java
package countdownlatch;

public class DemoNonCountDownLatch {
	
	private int count = 2000;
 
	public void dem() {
		Thread thread1 = new Thread(new Runnable() {
			public void run() {
				for (int i = 0; i < 1000; i++) {
					count--;
				}
			}
		});
         
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				for (int i = 0; i < 1000; i++) {
					count--;
				}
			}
		});
         
		thread1.start();
		thread2.start();
 
		try {
			thread1.join();
			thread2.join();
		} catch (InterruptedException ignored) {
		}	
		
		System.out.println("Count = " + count);
    }
	
	public static void main(String[] args) {
		DemoNonCountDownLatch demoNonCountDownLatch = new DemoNonCountDownLatch();
		demoNonCountDownLatch.dem();
	}
}

Kết quả sau khi biên dịch chương trình:

ketqua vi du khong su dung countdownlatch PNG

Với đoạn code trên thì khi thực thi chương trình, kết quả mà chúng ta mong muốn là giá trị của biến count sẽ bằng 0, nhưng vì thread1thread2 lúc này là 2 luồng chạy song song nên kết quả biến count sau mỗi lần biên dịch sẽ khác nhau. Vì biến count được cả hai thread1thread2 cùng đồng thời tác động và thay đổi giá trị nên sẽ xảy ra trường hợp thread1 chưa xử lý xong (giảm count đi 1) thì thread2 đã thực hiện tác động tới biến count này nên giá trị của count sẽ thay đổi và không theo ý muốn của chúng ta.

Vì vậy, để giải quyết trường hợp này, chúng ta có thể sử dụng từ khóa synchronized để đảm bảo rằng việc giảm biến count đi 1 sẽ được xử lý một cách tuần tự, tức là tại 1 thời điểm chỉ có duy nhất một Thread được thao tác với biến count:

UseSynchronizedMethod.java
package countdownlatch;

import java.util.concurrent.CountDownLatch;

public class DemoCountDownLatch {
	
	public CountDownLatch count = new CountDownLatch(2000);

	public void doWork() {
		Thread thread1 = new Thread(new Runnable() {
			public void run() {
				for (int i = 0; i < 1000; i++) {
					count.countDown();	// giảm giá trị của biến count
				}
			}
		});
         
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				for (int i = 0; i < 1000; i++) {
					count.countDown();
				}
			}
		});
         
		thread1.start();
		thread2.start();
 
		try {
			count.await();
		} catch (InterruptedException ignored) {
        
		}
		System.out.println("Count = " + count.getCount());
	}
	
	public static void main(String[] args) {
		DemoCountDownLatch demo = new DemoCountDownLatch();
		demo.doWork();
	}
	
}

Kết quả sau khi biên dịch chương trình:

ketqua vi du dung synchronized PNG

Trong đoạn code trên, từ khóa synchronized ở phương thức giamCount() đã bảo đảm rằng tại một thời điểm chỉ có duy nhất 1 Thread được gọi vào hàm để xử lý.

Ngoài ra, như nội dung chính của phần này đó là chúng ta có thể dùng CountDownLatch để giải quyết vấn đề này:

DemoCountDownLatch.java
package countdownlatch;

import java.util.concurrent.CountDownLatch;

public class DemoCountDownLatch {
	
	public CountDownLatch count = new CountDownLatch(2000);

	public void doWork() {
		Thread thread1 = new Thread(new Runnable() {
			public void run() {
				for (int i = 0; i < 1000; i++) {
					count.countDown();	// giảm giá trị của biến count đi 1
				}
			}
		});
         
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				for (int i = 0; i < 1000; i++) {
					count.countDown();
				}
			}
		});
         
		thread1.start();
		thread2.start();
 
		try {
			count.await();
		} catch (InterruptedException ignored) {
        
		}
		System.out.println("Count = " + count.getCount());
	}
	
	public static void main(String[] args) {
		DemoCountDownLatch demo = new DemoCountDownLatch();
		demo.doWork();
	}
	
}

Kết quả sau khi biên dịch chương trình:

ketqua vi du su dung countdownlatch PNG

Giải thích hoạt động của chương trình trên:

Đoạn code public CountDownLatch count = new CountDownLatch(2000); sẽ khởi tạo một đối tượng CountDownLatch có tên là count với giá trị là 2000. Còn để giảm dần giá trị của count thì lớp CountDownLatch cung cấp cho chúng ta phương thức countDown(): count.countDown();. Ngoài ra, chúng ta còn thấy dòng code count.await();, phương thức await() sẽ đợt tất cả các tiến trình xử lý của CountDownLatch hoàn thành (tương tự như phương thức join() trong Thread).

2. Lời kết

Trong bài này, tôi đã hướng dẫn các bạn tìm hiểu về lớp CountDownLatch trong Java. Đây là bài cuối cùng trong chương này. Sang chương sau, chúng ta sẽ bước sang một chương mới - đó là chương Exception. Các bạn theo dõi nhé!

Cùng chuyên mục:

Khi nào dùng Default Methods trong Java 8

Khi nào dùng Default Methods trong Java 8

Ở 2 bài trước chúng ta đã tìm hiểu 2 tính năng mới của Java…

Cách chuyển chữ hoa thành chữ thường trong Java

Cách chuyển chữ hoa thành chữ thường trong Java

Trong bài viết này chúng ta sẽ tìm hiểu về cách chuyển đổi chữ in…

Bài tập tính tổng các số tự nhiên trong Java

Bài tập tính tổng các số tự nhiên trong Java

Các số dương 1, 2, 3, 4, ... được gọi là các số tự nhiên,…

Cách chuyển chữ thường thành chữ hoa trong Java

Cách chuyển chữ thường thành chữ hoa trong Java

Trong chuỗi có thể vừa có ký tự thường vừa có ký tự hoa, nhưng…

Cách viết hoa ký tự đầu tiên trong Java

Cách viết hoa ký tự đầu tiên trong Java

Để hiểu được bài này, các bạn cần có kiến thức căn bản về Java…

Hướng dẫn chuyển đổi giờ phút giây trong Java

Hướng dẫn chuyển đổi giờ phút giây trong Java

Để hiểu được chương trình, các bạn cần có kiến thức cơ bản về Java.…

Cách lấy thời gian hiện tại trong Java

Cách lấy thời gian hiện tại trong Java

Để hiểu được bài viết này, các bạn cần có kiến thức cơ bản sau…

Cách làm tròn số trong Java

Cách làm tròn số trong Java

Khi thực hiện tính toán, việc kết quả ra một con số thập phân dài…

Cách tìm ma trận chuyển vị trong Java

Cách tìm ma trận chuyển vị trong Java

Quá trình hoán đổi giữa hàng và cột được gọi là chuyển vị của ma…

Cách chuyển ArrayList thành mảng và ngược lại trong Java

Cách chuyển ArrayList thành mảng và ngược lại trong Java

Để hiểu được bài này, các bạn cần có kiến thức cơ bản về mảng…

Cách nối hai mảng trong Java

Cách nối hai mảng trong Java

Mình sẽ thực hiện hai chương trình nối mảng. Chương trình thứ nhất nối hai…

Cách xóa khoảng trắng của chuỗi trong Java

Cách xóa khoảng trắng của chuỗi trong Java

Mình sẽ thực hiện hai chương trình khác nhau để các bạn có thể hiểu…

In ra tam giác bằng ký tự * và số trong Java

In ra tam giác bằng ký tự * và số trong Java

Mình sẽ giới thiệu cách để in ra các tam giác bằng ký tự *…

Tìm số lớn nhất trong mảng Java

Tìm số lớn nhất trong mảng Java

Các bạn cần tìm hiểu về mảng, cách khởi tạo và in mảng trong Java…

Tìm ước của một số nguyên trong Java

Tìm ước của một số nguyên trong Java

Trong bài viết này chúng ta sẽ tìm hiểu cách tìm tất cả các ước…

Cách kiểm tra số hoàn hảo trong Java

Cách kiểm tra số hoàn hảo trong Java

Cách kiểm tra số đối xứng trong Java

Cách kiểm tra số đối xứng trong Java

Trong bài viết này chúng ta sẽ kiểm tra một số có phải là số…

Đảo ngược một số trong Java

Đảo ngược một số trong Java

Mình sẽ giới thiệu các bạn cách đảo ngược một số sử dụng vòng lặp…

Tìm bội chung nhỏ nhất trong Java

Tìm bội chung nhỏ nhất trong Java

Mình sẽ sử dụng hai cách khác nhau để tìm BCNN. Cách thứ nhất mình…

Cách hoán đổi hai số trong Java

Cách hoán đổi hai số trong Java

Trong phần này mình sẽ sử dụng một biến tạm temp() làm biến trung gian…

Top