Câu hỏi Khối Java được đồng bộ hóa cho lớp .class


Mã java này có nghĩa là gì? Liệu nó có khóa trên tất cả các vật thể của MyClass?

synchronized(MyClass.class) {
   //is all objects of MyClass are thread-safe now ??
}

Và cách mã trên khác với mã này:

synchronized(this) {
   //is all objects of MyClass are thread-safe now ??
}

76
2018-01-13 11:33


gốc


Liên quan: stackoverflow.com/questions/437620/… - finnw


Các câu trả lời:


Đoạn trích synchronized(X.class) sử dụng cá thể lớp như một màn hình. Vì chỉ có một cá thể lớp (đối tượng biểu diễn siêu dữ liệu lớp khi chạy) một luồng có thể nằm trong khối này.

Với synchronized(this) khối được bảo vệ bởi cá thể. Đối với mỗi trường hợp chỉ có một luồng có thể nhập vào khối.

synchronized(X.class) được sử dụng để đảm bảo rằng có chính xác một Chủ đề trong khối. synchronized(this) đảm bảo rằng có chính xác một chủ đề cho mỗi trường hợp. Nếu điều này làm cho mã thực tế trong khối thread-safe phụ thuộc vào việc thực hiện. Nếu đột biến chỉ trạng thái của cá thể synchronized(this) Là đủ.


118
2018-01-13 11:35



"như nhiều chủ đề có thể nhập khối như có ví dụ" ngụ ý rằng hình thức thứ hai hoạt động như một semaphore đó là không đúng sự thật. Bạn nên nói một cái gì đó như: "đồng bộ (điều này) đảm bảo rằng chỉ có một thread có thể nhập vào khối cho một trường hợp nhất định của lớp". - liwp
Đã sửa. Tôi định nói điều đó. - Thomas Jung
ví dụ class vs instance là gì? - Weishi Zeng


Để thêm vào các câu trả lời khác:

static void myMethod() {
  synchronized(MyClass.class) {
    //code
  }
}

tương đương với

static synchronized void myMethod() {
  //code
}

void myMethod() {
  synchronized(this) {
    //code
  }
}

tương đương với

synchronized void myMethod() {
  //code
}

69
2018-01-13 12:45



Nó đã cho tôi một đọc thứ hai để nắm bắt rằng hai ví dụ đầu tiên có từ khóa "tĩnh". Chỉ cần chỉ ra rằng những người khác có thể đã nhìn thấy điều này và bỏ lỡ nó. Không có từ khóa tĩnh, hai ví dụ đầu tiên sẽ không giống nhau. - kurtzbot
Những ví dụ đó KHÔNG tương đương! Các phương thức đồng bộ được "đồng bộ" như một lỗ khi một luồng cố gọi các phương thức. Các khối, mặt khác, có thể có mã ở trên và bên dưới chúng, có thể được thực thi từ nhiều luồng. Họ chỉ đồng bộ hóa trong khối! Điều đó không giống nhau! - JacksOnF1re
public static Singleton getInstance () {if (instance == null) {đồng bộ (Singleton.class) {instance = new Singleton (); }} thể hiện trả về; } - JacksOnF1re
Toàn bộ vấn đề là ở đó Là không có mã bên ngoài synchronized khối. Điều đó làm cho chúng tương đương. Nếu bạn thay đổi một ví dụ, chúng thực sự không còn giống nhau nữa. - Jorn


Không, lần đầu tiên sẽ có khóa trên định nghĩa lớp MyClass, không phải tất cả các trường hợp của nó. Tuy nhiên, nếu được sử dụng trong một cá thể, điều này sẽ chặn tất cả các phiên bản khác một cách hiệu quả vì chúng chia sẻ một định nghĩa lớp đơn.

Thứ hai sẽ chỉ nhận khóa trên phiên bản hiện tại.

Để biết liệu điều này có làm cho chủ đề của bạn an toàn không, đó là một câu hỏi phức tạp hơn nhiều - chúng tôi cần xem mã của bạn!


21
2018-01-13 11:35



có, MyClass.class có thể là bất kỳ biến tĩnh nào và có cùng tác dụng. - pstanton