2012-03-03 31 views
10

Tôi có câu hỏi liên quan đến lời gọi phương thức nhiều luồng trong Java. Hãy nói rằng chúng tôi có một đối tượng singleton, và các lớp học tuyên bố như sau:Đồng thời gọi phương thức Java của đối tượng đơn lẻ

public class SomeClass { 
    public void someMethod(SomeValueObject object) { 

     if (object.condition1) { 
      ... 
     } 
     if (object.condition2) { 
      ... 
     } 
     if (object.condition3) { 
      ... 
     } 

    } 
} 

Tôi tự hỏi nếu đối tượng singleton này đang được đồng thời truy cập và someMethod của nó gọi với trường hợp SomeValueObject riêng biệt, có khả năng một số chủ đề ngẫu nhiên thay đổi tham chiếu của đối tượng cho lời gọi phương thức của một chuỗi khác và làm hỏng mọi thứ? Và những gì về các lĩnh vực được tạo ra bên trong phạm vi phương pháp? Điều tôi không biết, liệu có bất kỳ ngữ cảnh Phương thức riêng biệt nào được tạo ra cho mỗi luồng gọi phương thức hay ngữ cảnh Phương thức là giống nhau đối với tất cả các chuỗi gọi không? Nếu đây là trường hợp thứ hai, tôi đoán tôi cần từ khóa an toàn chủ đề mới hoặc sử dụng các phiên bản SomeClass riêng biệt cho mỗi chuỗi (trong trường hợp tôi cần thực thi nhanh hơn tối ưu hóa bộ nhớ). Bạn vui lòng giải thích vấn đề này cho tôi được không?

P.S. Cảm ơn tất cả những người trả lời của bạn!

Trả lời

13

Nếu mọi thứ đều là cục bộ, phương pháp của bạn an toàn theo luồng. Mỗi luồng sẽ có đối số đối tượng riêng của nó trên ngăn xếp và chúng sẽ không ảnh hưởng lẫn nhau. Bạn có thể có các vấn đề đồng thời nếu hai luồng gọi phương thức này với cùng một đối tượng như đối số, hoặc nếu hai đối tượng đó chia sẻ một số trạng thái, nhưng đó không phải là vấn đề của singleton. Đó là vấn đề của trạng thái được chia sẻ, phải được đồng bộ hóa đúng cách.

Quy tắc chung của ngón tay cái: đối tượng không trạng thái là an toàn chỉ. Một đối tượng có trạng thái bất biến là thread-safe. Một đối tượng có trạng thái có thể thay đổi không an toàn cho luồng nếu nó không đồng bộ hóa quyền truy cập vào trạng thái được chia sẻ đúng cách.

8

Không, chủ đề sẽ không thể thay đổi biến cục bộ của một chuỗi khác.

Tất cả các biến được tạo trong phạm vi của phương thức [biến cục bộ] - bao gồm tham số được phân bổ trên ngăn xếp của chuỗi cụ thể và do đó không được chia sẻ giữa hai luồng.

Tuy nhiên - tất cả các trường của lớp không an toàn và nếu một chuỗi thay đổi chúng - nó sẽ được phản ánh trong tất cả.

3

Mỗi luồng có ngăn xếp thực thi riêng. Vùng nhớ này chứa tất cả các biến cục bộ và các tham số của phương thức. Khi hai luồng thực hiện cùng một mã, cả hai đều sử dụng các ngăn xếp riêng biệt.

Do đó, không thể thay đổi giá trị của tham số phương pháp hoặc biến cục bộ theo một chuỗi khác.

2

Phương pháp cơ bản là một đoạn mã. Khi một nhóm các chủ đề gọi một phương thức, một bản sao riêng biệt của phương thức tồn tại trên mỗi ngăn xếp của luồng, do đó các biến cục bộ không can thiệp vào eachother.

Nếu bổ sung, tất cả các thông số đều khác nhau cho mỗi luồng, thì có cách ly hoàn hảo, trừ khi phương thức của bạn hoạt động trên dữ liệu được chia sẻ bổ sung bên trong mã của nó.

3

Những gì người khác nói. Mặc dù để nit-pick: trong java chỉ các biến nguyên thủy và các tham số (int, long, boolean, vv) được cấp phát trên stack tất cả các đối tượng khác được cấp phát trên heap và chỉ các tham chiếu được lưu trữ trên stack. Nhưng những người khác cho biết mỗi lời gọi của phương pháp này sẽ thấy bản sao của các biến cục bộ của riêng nó.

Lưu ý rằng đối tượng (trái ngược với nguyên thủy) được truyền vì tham số không nhất thiết phải duy nhất cho mỗi lần gọi, vì các tham số objet chỉ là tham chiếu. Vì vậy, nếu bạn truyền cùng một đối tượng đầu vào cho phương thức hai lần thì cả hai sẽ hoạt động trên cùng một đầu vào.

Các vấn đề liên quan