Cách sử dụng wait, notify, notifyAll trong Java thread (Có ví dụ minh họa)
4 phút đọc10/06/2025
Về tác giả
I’m passionate about web development and sharing my insights through articles, with over 8 years of experience. I hope these sharings inspire you and help build a strong web development community.
@#@
Tôi đam mê phát triển web và chia sẻ những hiểu biết của mình thông qua các bài viết, với hơn 8 năm kinh nghiệm. Tôi hy vọng những chia sẻ này sẽ truyền cảm hứng cho các bạn và giúp xây dựng một cộng đồng phát triển web mạnh mẽ.
Cập nhật thông tin mới nhấtNhận các thông tin mới nhất về mối đe dọa, báo cáo an ninh mạng từ CyStack về hòm thư điện tử của bạn
{"success":true,"head":"<title>Cách sử dụng wait, notify, notifyAll trong Java thread (Có ví dụ minh họa) - CyStack Tutorial</title>\n<meta name=\"description\" content=\"Học cách sử dụng wait(), notify(), và notifyAll() trong Java để xây dựng các hệ thống đa luồng ổn định hơn và tránh được những sai lầm phổ biến khi đồng bộ hóa luồng.\"/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-video-preview:-1, max-image-preview:large\"/>\n<link rel=\"canonical\" href=\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/\" />\n<meta property=\"og:locale\" content=\"en_US\" />\n<meta property=\"og:type\" content=\"article\" />\n<meta property=\"og:title\" content=\"Cách sử dụng wait, notify, notifyAll trong Java thread (Có ví dụ minh họa) - CyStack Tutorial\" />\n<meta property=\"og:description\" content=\"Học cách sử dụng wait(), notify(), và notifyAll() trong Java để xây dựng các hệ thống đa luồng ổn định hơn và tránh được những sai lầm phổ biến khi đồng bộ hóa luồng.\" />\n<meta property=\"og:url\" content=\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/\" />\n<meta property=\"og:site_name\" content=\"CyStack Tutorial\" />\n<meta property=\"article:tag\" content=\"vi\" />\n<meta property=\"article:section\" content=\"Java\" />\n<meta property=\"og:updated_time\" content=\"2026-08-03T17:11:43+07:00\" />\n<meta property=\"og:image\" content=\"https://s2.cystack.net/tutorial/10123106/wait-notify-notifyall-trong-java-thread-1024x538.jpg\" />\n<meta property=\"og:image:secure_url\" content=\"https://s2.cystack.net/tutorial/10123106/wait-notify-notifyall-trong-java-thread-1024x538.jpg\" />\n<meta property=\"og:image:width\" content=\"1024\" />\n<meta property=\"og:image:height\" content=\"538\" />\n<meta property=\"og:image:alt\" content=\"Giao tiếp giữa các thread trong Java\" />\n<meta property=\"og:image:type\" content=\"image/jpeg\" />\n<meta property=\"article:published_time\" content=\"2025-06-10T12:32:27+07:00\" />\n<meta property=\"article:modified_time\" content=\"2026-08-03T17:11:43+07:00\" />\n<meta name=\"twitter:card\" content=\"summary_large_image\" />\n<meta name=\"twitter:title\" content=\"Cách sử dụng wait, notify, notifyAll trong Java thread (Có ví dụ minh họa) - CyStack Tutorial\" />\n<meta name=\"twitter:description\" content=\"Học cách sử dụng wait(), notify(), và notifyAll() trong Java để xây dựng các hệ thống đa luồng ổn định hơn và tránh được những sai lầm phổ biến khi đồng bộ hóa luồng.\" />\n<meta name=\"twitter:image\" content=\"https://s2.cystack.net/tutorial/10123106/wait-notify-notifyall-trong-java-thread-1024x538.jpg\" />\n<meta name=\"twitter:label1\" content=\"Written by\" />\n<meta name=\"twitter:data1\" content=\"Bao Tran\" />\n<meta name=\"twitter:label2\" content=\"Time to read\" />\n<meta name=\"twitter:data2\" content=\"4 minutes\" />\n<script type=\"application/ld+json\" class=\"rank-math-schema\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https://blog.cystack.org/tutorial/#person\",\"name\":\"CyStack Tutorial\"},{\"@type\":\"WebSite\",\"@id\":\"https://blog.cystack.org/tutorial/#website\",\"url\":\"https://blog.cystack.org/tutorial\",\"name\":\"CyStack Tutorial\",\"publisher\":{\"@id\":\"https://blog.cystack.org/tutorial/#person\"},\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https://s2.cystack.net/tutorial/10123106/wait-notify-notifyall-trong-java-thread.jpg\",\"url\":\"https://s2.cystack.net/tutorial/10123106/wait-notify-notifyall-trong-java-thread.jpg\",\"width\":\"2400\",\"height\":\"1260\",\"caption\":\"Giao ti\\u1ebfp gi\\u1eefa c\\u00e1c thread trong Java\",\"inLanguage\":\"en-US\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":\"1\",\"item\":{\"@id\":\"https://blog.cystack.org/tutorial\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"position\":\"2\",\"item\":{\"@id\":\"https://blog.cystack.org/tutorial/vi/category/java/\",\"name\":\"Java\"}},{\"@type\":\"ListItem\",\"position\":\"3\",\"item\":{\"@id\":\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/\",\"name\":\"C\\u00e1ch s\\u1eed d\\u1ee5ng wait, notify, notifyAll trong Java thread (C\\u00f3 v\\u00ed d\\u1ee5 minh h\\u1ecda)\"}}]},{\"@type\":\"WebPage\",\"@id\":\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/#webpage\",\"url\":\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/\",\"name\":\"C\\u00e1ch s\\u1eed d\\u1ee5ng wait, notify, notifyAll trong Java thread (C\\u00f3 v\\u00ed d\\u1ee5 minh h\\u1ecda) - CyStack Tutorial\",\"datePublished\":\"2025-06-10T12:32:27+07:00\",\"dateModified\":\"2026-08-03T17:11:43+07:00\",\"isPartOf\":{\"@id\":\"https://blog.cystack.org/tutorial/#website\"},\"primaryImageOfPage\":{\"@id\":\"https://s2.cystack.net/tutorial/10123106/wait-notify-notifyall-trong-java-thread.jpg\"},\"inLanguage\":\"en-US\",\"breadcrumb\":{\"@id\":\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/#breadcrumb\"}},{\"@type\":\"Person\",\"@id\":\"https://blog.cystack.org/tutorial/author/baotran/\",\"name\":\"Bao Tran\",\"url\":\"https://blog.cystack.org/tutorial/author/baotran/\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https://secure.gravatar.com/avatar/0cdd33c02ec4a531fcf557b9c1ccc276df0c69031b2382c959bcf335248e840c?s=96&d=mm&r=g\",\"url\":\"https://secure.gravatar.com/avatar/0cdd33c02ec4a531fcf557b9c1ccc276df0c69031b2382c959bcf335248e840c?s=96&d=mm&r=g\",\"caption\":\"Bao Tran\",\"inLanguage\":\"en-US\"}},{\"@type\":\"BlogPosting\",\"headline\":\"C\\u00e1ch s\\u1eed d\\u1ee5ng wait, notify, notifyAll trong Java thread (C\\u00f3 v\\u00ed d\\u1ee5 minh h\\u1ecda) - CyStack Tutorial\",\"keywords\":\"wait,notify,notifyAll,java\",\"datePublished\":\"2025-06-10T12:32:27+07:00\",\"dateModified\":\"2026-08-03T17:11:43+07:00\",\"articleSection\":\"Java\",\"author\":{\"@id\":\"https://blog.cystack.org/tutorial/author/baotran/\",\"name\":\"Bao Tran\"},\"publisher\":{\"@id\":\"https://blog.cystack.org/tutorial/#person\"},\"description\":\"H\\u1ecdc c\\u00e1ch s\\u1eed d\\u1ee5ng wait(), notify(), v\\u00e0 notifyAll() trong Java \\u0111\\u1ec3 x\\u00e2y d\\u1ef1ng c\\u00e1c h\\u1ec7 th\\u1ed1ng \\u0111a lu\\u1ed3ng \\u1ed5n \\u0111\\u1ecbnh h\\u01a1n v\\u00e0 tr\\u00e1nh \\u0111\\u01b0\\u1ee3c nh\\u1eefng sai l\\u1ea7m ph\\u1ed5 bi\\u1ebfn khi \\u0111\\u1ed3ng b\\u1ed9 h\\u00f3a lu\\u1ed3ng.\",\"name\":\"C\\u00e1ch s\\u1eed d\\u1ee5ng wait, notify, notifyAll trong Java thread (C\\u00f3 v\\u00ed d\\u1ee5 minh h\\u1ecda) - CyStack Tutorial\",\"@id\":\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/#richSnippet\",\"isPartOf\":{\"@id\":\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/#webpage\"},\"image\":{\"@id\":\"https://s2.cystack.net/tutorial/10123106/wait-notify-notifyall-trong-java-thread.jpg\"},\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https://blog.cystack.org/tutorial/vi/2025/06/10/wait-notify-notifyall-trong-java-thread/#webpage\"}}]}</script>\n"}
Lớp Object trong Java có ba phương thức final cho phép các thread giao tiếp với nhau về trạng thái khóa (lock) của một tài nguyên. Các phương thức này là wait(), notify() và notifyAll(). Hôm nay, chúng ta sẽ cùng tìm hiểu về chúng để nắm vững cách quản lý đồng bộ hóa giữa các luồng một cách hiệu quả.

wait(), notify() và notifyAll() trong Java
Chú ý: thread gọi các phương thức này trên một đối tượng bất kỳ cần phải nắm giữ monitor (cơ chế khóa và đồng bộ hóa) của đối tượng đó, nếu không sẽ gây ra lỗi java.lang.IllegalMonitorStateException.
wait()
Phương thức wait() của lớp Object có ba phiên bản. Một phiên bản sẽ khiến thread hiện tại đợi vô thời hạn cho đến khi một thread khác gọi phương thức notify() hoặc notifyAll() trên cùng đối tượng đó để đánh thức nó. Hai phiên bản còn lại đưa thread hiện tại vào trạng thái đợi trong một khoảng thời gian cụ thể trước khi nó tự động thức dậy.
notify()
Phương thức notify() chỉ đánh thức một thread duy nhất đang đợi trên đối tượng, và thread đó sẽ bắt đầu chạy. Do đó, nếu có nhiều thread cùng đang đợi trên một đối tượng, phương thức này sẽ chỉ đánh thức một thread trong số đó. Việc thread nào được chọn để đánh thức sẽ phụ thuộc vào cách hệ điều hành (OS) triển khai cơ chế quản lý thread.
notifyAll()
Phương thức notifyAll() đánh thức tất cả các thread đang đợi trên đối tượng. Tuy nhiên, thread nào được ưu tiên xử lý trước sẽ phụ thuộc vào hệ điều hành.
Các phương thức này có thể được dùng để triển khai bài toán kinh điển producer-consumer (sản xuất – tiêu thụ). Trong đó các consumer thread (thread tiêu thụ) đợi các đối tượng trong một Queue (hàng đợi), còn các producer thread (thread sản xuất) thì đưa đối tượng vào Queue và thông báo cho các thread đang đợi.
Hãy cùng xem một ví dụ cụ thể có nhiều thread cùng làm việc trên một đối tượng.
Message
Đây là một lớp Java Bean mà các thread sẽ làm việc trên đó và gọi các phương thức wait() và notify().
package com.journaldev.concurrency;
public class Message {
private String msg;
public Message(String str){
this.msg=str;
}
public String getMsg() {
return msg;
}
public void setMsg(String str) {
this.msg=str;
}
}
Waiter
Đây là một lớp mà thread của nó sẽ đợi các thread khác gọi phương thức notify() (hoặc notifyAll()) để hoàn tất quá trình xử lý.
Lưu ý rằng thread Waiter sở hữu monitor của đối tượng Message thông qua việc sử dụng khối synchronized.
package com.journaldev.concurrency;
public class Waiter implements Runnable{
private Message msg;
public Waiter(Message m){
this.msg=m;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (msg) {
try{
System.out.println(name+" waiting to get notified at time:"+System.currentTimeMillis());
msg.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(name+" waiter thread got notified at time:"+System.currentTimeMillis());
//xử lý message
System.out.println(name+" processed: "+msg.getMsg());
}
}
}
Notifier
Lớp này sẽ thực hiện xử lý trên đối tượng Message, sau đó gọi phương thức notify() để đánh thức các thread đang đợi đối tượng Message đó. Lưu ý rằng khối synchronized cũng được sử dụng để thread Notifier có thể sở hữu monitor của đối tượng Message.
package com.journaldev.concurrency;
public class Notifier implements Runnable {
private Message msg;
public Notifier(Message msg) {
this.msg = msg;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name+" started");
try {
Thread.sleep(1000);
synchronized (msg) {
msg.setMsg(name+" Notifier work done");
msg.notify();
// msg.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
WaitNotifyTest
Đây là lớp kiểm tra dùng để tạo ra nhiều thread Waiter và Notifier, sau đó khởi chạy chúng.
package com.journaldev.concurrency;
public class WaitNotifyTest {
public static void main(String[] args) {
Message msg = new Message("process it");
Waiter waiter = new Waiter(msg);
new Thread(waiter,"waiter").start();
Waiter waiter1 = new Waiter(msg);
new Thread(waiter1, "waiter1").start();
Notifier notifier = new Notifier(msg);
new Thread(notifier, "notifier").start();
System.out.println("All the threads are started");
}
}
Khi ta chạy chương trình trên, ta sẽ quan sát thấy chương trình không kết thúc. Lý do là vì có hai thread đang đợi trên đối tượng Message, trong khi phương thức notify() chỉ đánh thức một thread, nên thread còn lại vẫn tiếp tục đợi tín hiệu thông báo.
waiter waiting to get notified at time:1356318734009
waiter1 waiting to get notified at time:1356318734010
All the threads are started
notifier started
waiter waiter thread got notified at time:1356318735011
waiter processed: notifier Notifier work done
Nếu ta comment lệnh gọi notify() và bỏ comment lệnh gọi notifyAll() trong lớp Notifier, kết quả output sẽ cho thấy chương trình chạy thành công và kết thúc.
waiter waiting to get notified at time:1356318917118
waiter1 waiting to get notified at time:1356318917118
All the threads are started
notifier started
waiter1 waiter thread got notified at time:1356318918120
waiter1 processed: notifier Notifier work done
waiter waiter thread got notified at time:1356318918120
waiter processed: notifier Notifier work done
Do phương thức notifyAll() đánh thức cả hai thread Waiter, chương trình sẽ hoàn tất và tự kết thúc sau khi thực thi xong.
Tổng kết
Trên đây là những điểm chính về wait(), notify() và notifyAll() trong Java. Hãy nhớ nắm vững cách dùng chúng vào việc quản lý trạng thái và tương tác giữa các luồng để tránh các vấn đề như tranh chấp dữ liệu và deadlock trong ứng dụng đa luồng của bạn.