Khai báo một biến tĩnh trong Java, có nghĩa là sẽ chỉ có một bản sao, bất kể có bao nhiêu đối tượng của lớp được tạo. Biến sẽ có thể truy cập được ngay cả khi không có Objects
tạo. Tuy nhiên, các chủ đề có thể có các giá trị lưu trữ cục bộ của nó.
Khi một biến là biến động và không tĩnh , sẽ có một biến cho mỗi biến Object
. Vì vậy, trên bề mặt có vẻ như không có sự khác biệt so với một biến thông thường nhưng hoàn toàn khác với tĩnh . Tuy nhiên, ngay cả với Object
các trường, một luồng có thể lưu trữ giá trị biến cục bộ.
Điều này có nghĩa là nếu hai luồng cập nhật đồng thời một biến của cùng một đối tượng và biến đó không được khai báo là không ổn định, có thể xảy ra trường hợp một trong các luồng có trong bộ đệm có giá trị cũ.
Ngay cả khi bạn truy cập một giá trị tĩnh thông qua nhiều luồng, mỗi luồng có thể có bản sao lưu trong bộ nhớ cache cục bộ của nó! Để tránh điều này, bạn có thể khai báo biến là biến động tĩnh và điều này sẽ buộc luồng phải đọc mỗi lần giá trị toàn cục.
Tuy nhiên, không ổn định không phải là một thay thế cho đồng bộ hóa thích hợp!
Ví dụ:
private static volatile int counter = 0;
private void concurrentMethodWrong() {
counter = counter + 5;
//do something
counter = counter - 5;
}
Thực hiện concurrentMethodWrong
đồng thời nhiều lần có thể dẫn đến giá trị cuối cùng của bộ đếm khác 0!
Để giải quyết vấn đề, bạn phải thực hiện khóa:
private static final Object counterLock = new Object();
private static volatile int counter = 0;
private void concurrentMethodRight() {
synchronized (counterLock) {
counter = counter + 5;
}
//do something
synchronized (counterLock) {
counter = counter - 5;
}
}
Hoặc sử dụng AtomicInteger
lớp học.