Mục đích ở đây là để giá trị của biến được đồng bộ giữa các thread. 2 cách làm ở đây là cách sử dụng cơ chế monitor (quan trắc/theo dõi) bằng cách đặt từ khóa synchronized ở phía ngoài phương thức hay bên trong phương thức.
- Một phương thức cần synchroized cần phải có cơ chế theo dõi/quan trắc (để biến giá trị cần đồng bộ bằng bao nhiêu) trước khi nó thực hiện.
- Với phương thức của class (method có từ khóa static đứng trước), trình quan trắc gắn với đối tượng của Class cho các class của phương thức được sử dụng.
- Với phương thức của instance (phương thức cần từ khóa new để khởi tạo class, method thuộc class đó), trình quan trắc/theo dõi sử dụng từ khóa this (đối tượng mà phương thức được triệu gọi) là được dùng.
Tất cả các ví dụ dưới đây, đều đủ cả 4 loại: biến loại static và non-static, method loại static và non-static.
Cách 1:
public class Test { int count; synchronized void bump() { count++; } static int classCount; static synchronized void classBump() { classCount++; } }
Cách 2
class BumpTest { int count; void bump() { synchronized (this) { count++; } } static int classCount; static void classBump() { try { synchronized (Class.forName("BumpTest")) { classCount++; } } catch (ClassNotFoundException e) { } }
}
2 cách là như nhau cho cùng 1 mục đích. Nếu không khai báo synchronized
ở ngoài variable/method, thì phải khai báo bên trong. Có trường hợp thì dùng từ khóa this
, có trường hợp thì dùng Java reflection synchronized (Class.forName("BumpTest"))
. Cùng 1 mục đích giữ cho 2 giá trị có thể đồng bộ được với nhau trong môi trường Multi-thread, concurrent, có 2 cách làm khác nhau, cả với instance variable, instance method, class variable (biến mà có static đứng trước), class method (phương thức mà có static đứng trước).
Tài liệu tham chiếu: Đặc tả ngôn ngữ Java - language level 19: https://docs.oracle.com/javase/specs/jls/se19/html/jls-8.html#jls-8.4.3.6
Mã nguồn https://gist.github.com/donhuvy/94dc3edd94890b87721f1530b115976b#file-test-java-L5