GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java Core Multi-Thread Sử dụng CountDownLatch trong Java

Sử dụng CountDownLatch trong Java

Đăng vào 09/03/2018 . Được đăng bởi GP Coder . 6664 Lượt xem . Toàn màn hình

CountDownLatch được sử dụng để đảm bảo rằng một tác vụ chờ các Thread khác hoàn thành trước khi nó bắt đầu thực thi.

Khi chúng ta tạo ra một đối tượng của CountDownLatch, chúng ta chỉ định số lượng các Thread cần chờ đợi, tất cả các Thread đó được yêu cầu phải đếm ngược bằng cách gọi CountDownLatch.countDown() khi chúng đã hoàn thành. Ngay sau khi tính đến số 0, nhiệm vụ chờ đợi bắt đầu chạy.

Ví dụ: Một chương trình chỉ được start sau khi 3 service của nó đã được start. Với yêu cầu này, chúng ta có thể sử dụng phương thức join() của lớp Thread hoặc sử dụng lớp CountDownLatch.

Nội dung

  • 1 Ví dụ sử dụng Thread.join()
  • 2 Ví dụ sử dụng CountDownLatch

Ví dụ sử dụng Thread.join()

Đầu tiên chúng ta hãy xem chương trình sử dụng phương thức join() của lớp Thead:

ServiceOne.java


package com.gpcoder.countdownlatch.join;

public class ServiceOne implements Runnable {

	@Override
	public void run() {
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Started service One");
	}
}

ServiceTwo.java


package com.gpcoder.countdownlatch.join;

public class ServiceTwo implements Runnable {

	@Override
	public void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Started service Two");
	}

}

ServiceThree.java


package com.gpcoder.countdownlatch.join;

public class ServiceThree implements Runnable {

	@Override
	public void run() {
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Started service three");
	}

}

Chương trình chính phải chờ 3 service ServiceOne và ServiceTwo hoàn thành trước khi start.


package com.gpcoder.countdownlatch.join;


public class ThreadJoinExample {

	public static void main(String[] args) {

		// making two threads for 3 services
		Thread service1 = new Thread(new ServiceOne());
		Thread service2 = new Thread(new ServiceTwo());
		Thread service3 = new Thread(new ServiceThree());

		service1.start();
		service2.start();
		service3.start();

		// using thread.join() to make sure that the execution of main thread only
		// finishes ones 3 services have executed
		try {
			System.out.println("Waiting for 3 services have started ... ");
			service1.join();
			service2.join();
			service3.join();
			System.out.println("Starting main Thread ... ");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Done!!!");
	}

}

Thực thi chương trình trên, ta có kết quả như sau:


Waiting for 3 services have started ... 
Started service Two
Started service One
Started service three
Starting main Thread ... 
Done!!!

Ví dụ sử dụng CountDownLatch

ServiceOne.java


package com.gpcoder.countdownlatch;

import java.util.concurrent.CountDownLatch;

public class ServiceOne implements Runnable {
	private final CountDownLatch latch;

	public ServiceOne(CountDownLatch latch) {
		this.latch = latch;
	}

	@Override
	public void run() {
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Started service One");
		latch.countDown();
	}
}

ServiceTwo.java


package com.gpcoder.countdownlatch;

import java.util.concurrent.CountDownLatch;

public class ServiceTwo implements Runnable {

	private final CountDownLatch latch;

	public ServiceTwo(CountDownLatch latch) {
		this.latch = latch;
	}

	@Override
	public void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Started service Two");
		latch.countDown();
	}

}

ServiceThree.java


package com.gpcoder.countdownlatch;

import java.util.concurrent.CountDownLatch;

public class ServiceThree implements Runnable {

	private final CountDownLatch latch;

	public ServiceThree(CountDownLatch latch) {
		this.latch = latch;
	}

	@Override
	public void run() {
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Started service three");
		latch.countDown();
	}

}

Chương trình chính phải chờ 3 service ServiceOne và ServiceTwo hoàn thành trước khi start.


package com.gpcoder.countdownlatch;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {

	public static void main(String[] args) {
		// intialising count down latch by 3, as it will wait for 3 threads to
		// finish execution
		final CountDownLatch latch = new CountDownLatch(3);

		// making two threads for 3 services
		Thread service1 = new Thread(new ServiceOne(latch));
		Thread service2 = new Thread(new ServiceTwo(latch));
		Thread service3 = new Thread(new ServiceThree(latch));

		service1.start();
		service2.start();
		service3.start();

		// latch waits till the count becomes 0
		// this way we can make sure that the execution of main thread only
		// finishes ones 3 services have executed
		try {
			System.out.println("Waiting for 3 services have started ... ");
			latch.await();
			System.out.println("Starting main Thread ... ");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Done!!!");
	}

}

Như bạn thấy, tôi đã khởi tạo đối tượng CountDownLatch  với tham số là 3 để chỉ ra rằng chương trình chính phải chờ 3 Thread hoàn thành, tức là countdown là 0 mới được phép thực thi.

Mỗi Thread (ServiceOne, ServiceTwo) khi hoàn thành phải gọi phương thức CountDownLatch.countDown() để thông báo là Thead này đã hoàn thành, tức là giảm giá trị countdown (countdown–).

Sử dụng phương thức CountDownLatch.await() để thông báo chương trình chính phải chờ các Thread hoàn thành trước khi nó bắt đầu.

Lưu ý: chúng ta có thể sử dụng phương thức CountDownLatch.await(long timeout, TimeUnit unit) để chỉ ra rằng chương trình chính phải chờ cho tới khi countdown là 0 hoặc sau khoản thời gian timeout.

Thực thi chương trình ta có kết quả như sau:


Waiting for 3 services have started ... 
Started service Two
Started service One
Started service three
Starting main Thread ... 
Done!!!

Như bạn thấy, cả 2 cách sử dụng phương thức Thread.join() và CountDownLatch kết quả của chương trình cũng không khác biệt. Tuy nhiên, nếu số lượng Thread của chương trình tăng lên thì bạn cần phải khai báo Thread.join() cho mỗi Thread. Điều này khá phiền phức, thay vào đó chúng ta nên sử dụng CountDownLatch cho trường hợp này.

Trong các ứng dụng thực tế, CountDownLatch thường được sử dụng để test các ứng dụng đa luồng. Bằng cách sử dụng CountDownLatch, nó có thể đảm bảo rằng nhiều luồng được kích hoạt yêu cầu đồng thời hoặc thực hiện mã cùng một lúc.

Trong bài tiếp theo, chúng ta sẽ tìm hiểu cách sử dụng CyclicBarrier, một lớp tiện ích khác cũng nằm trong gói java.util.Concurrent.

4.8
17
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Multi-Thread Được gắn thẻ: CountDownLatch, Multithreading

Sử dụng Fork/Join Framework với ForkJoinPool trong Java
Sử dụng CyclicBarrier trong Java

Có thể bạn muốn xem:

  • Hướng dẫn tạo và sử dụng ThreadPool trong Java (27/02/2018)
  • Vấn đề Nhà sản xuất (Producer) – Người tiêu dùng (Consumer) và đồng bộ hóa các luồng trong Java (23/09/2019)
  • Lập trình đa luồng trong Java (Java Multi-threading) (12/02/2018)
  • Thực thi nhiều tác vụ cùng lúc như thế nào trong Java? (01/02/2019)
  • Luồng Daemon (Daemon Thread) trong Java (14/02/2018)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (98058 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97699 lượt xem)
  • Giới thiệu Design Patterns (87762 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (86433 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83838 lượt xem)

Nội dung bài viết

  • 1 Ví dụ sử dụng Thread.join()
  • 2 Ví dụ sử dụng CountDownLatch

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link