2015-04-23 33 views
5

Loại câu hỏi tiếp theo là Why can't Java constructors be synchronized?: nếu không thể đồng bộ hóa hàm tạo của đối tượng, điều đó có nghĩa là không thể tạo hai phiên bản theo nghĩa đen cùng một lúc? Ví dụ:Có thể tạo hai trường hợp cùng một lúc không?

public class OutgoingMessage { 
    public OutgoingMessage() { 
     this.creationTime = new Date(); 
    } 
    Date creationTime; 
} 

Liệu creationDate.getTime() luôn trả về một giá trị khác? Tôi nhận thức được những điều cơ bản của đa nhiệm/đa luồng nhưng những gì về nhiều lõi CPU? Trong trường hợp đó hệ điều hành không phải chuyển đổi ngữ cảnh hoặc tôi sai ở đây?

+0

Ý của bạn là 'creationTime.getDate()' ? – RaGe

+0

Thậm chí bỏ qua đa lõi 'creationTime' vẫn có thể giống nhau cho hai đối tượng. –

+3

thực tế là đối tượng không hiển thị với các chủ đề khác cho đến khi nó được xây dựng không có nghĩa là 2 đối tượng không thể được xây dựng simulatneously – njzk2

Trả lời

7

nếu không thể đồng bộ hóa hàm tạo của đối tượng, điều đó có nghĩa là không thể tạo hai phiên bản theo đúng nghĩa đen cùng một lúc?

No. Là câu trả lời ở trạng thái câu hỏi khác, một hàm tạo không thể đồng bộ hóa đơn giản vì không có gì tồn tại để đồng bộ hóa trước khi hàm tạo được gọi. Bạn có thể làm một cái gì đó như thế này:

public OutgoingMessage(){ 
    synchronized(this){ 
     //synchronized constructor 
    } 
} 

Nhưng rồi câu hỏi trở thành: làm thế nào trên trái đất hai luồng sẽ truy cập vào cùng một constructor của cùng một ví dụ cùng một lúc? Họ không thể, bởi chính định nghĩa của cách các nhà thầu hoạt động. Đó là lý do tại sao bạn không thể đồng bộ hóa trên một hàm tạo bởi vì nó không có ý nghĩa gì cả.

Đó là không nói rằng hai thể hiện của một lớp không thể được xây dựng cùng một lúc.

+0

Oh-oh, đó là những gì tôi đã sợ. Một đối tượng khóa tĩnh tư nhân có làm việc cho mục đích này không? –

+0

@MiroKropacek Nó thực sự phụ thuộc vào chính xác những gì bạn đang cố gắng làm, nhưng chắc chắn, bạn có thể đồng bộ hóa trên một đối tượng khóa tĩnh để hạn chế các phần của constructor của bạn vào một Thread duy nhất. Bạn cũng có thể lấy ví dụ về đồng bộ hóa của BretC trên chính lớp đó. –

1

Nếu bạn muốn chắc chắn rằng khối mã bên trong constructor của bạn không bao giờ được thực hiện bởi nhiều hơn một thread cùng lúc, bạn có thể đồng bộ hóa trên lớp, ví dụ ...

public class MyClass { 
    public MyClass() { 
     synchronized(MyClass.class) { 
      // Thread unsafe code here! 
     } 
    } 
} 

Bạn không phải sử dụng "MyClass.class" nếu bạn không muốn, bạn có thể có một đối tượng "LOCK", ví dụ ...

public class MyClass { 
    private static final Object LOCK = new Object(); 

    public MyClass() { 
     synchronized(LOCK) { 
      // Thread unsafe code here! 
     } 
    } 
} 
Các vấn đề liên quan