2011-01-22 57 views
7

Các phương pháp chỉ sử dụng các biến cục bộ bên trong có gặp vấn đề về luồng không? Một nơi nào đó nó đã được đề cập rằng phương pháp với các biến địa phương được sao chép vào mỗi khung stack thread để làm việc với và không cần phải đồng bộ hóa cho thực hiện đa luồng, trừ khi nó sử dụng cấp lớp hoặc tham chiếu tĩnh/biến?Trong Java, các phương thức không sử dụng biến tĩnh hoặc lớp cần phải được đồng bộ hóa?

Trả lời

8

Nếu phương pháp của bạn chỉ hoạt động trên các tham số và biến cục bộ (trái ngược với thành viên của lớp) thì không có vấn đề về đồng bộ hóa nào cần phải lo lắng.

Nhưng ...

Điều này có nghĩa bất kỳ loại tài liệu tham khảo có thể thay đổi bạn sử dụng phải sống và chết chỉ trong phạm vi của phương pháp của bạn. (Loại tài liệu tham khảo bất di bất dịch là không phải là một vấn đề ở đây.) Ví dụ này là không có vấn đề:

int doSomething(int myParameter) 
{ 
    MyObject working_set = new MyObject(); 
    interim = working_set.doSomethingElse(myParameter); 
    return working_set.doSomethingElseAgain(interim); 
} 

Một ví dụ MyObject được tạo ra trong phương pháp của bạn, làm tất cả các công việc của mình trong phương pháp của bạn và ho ra máu, chờ đợi sẽ được GC hủy bỏ khi bạn thoát khỏi phương thức của mình.

này, mặt khác, có thể là một vấn đề:

int doSomething(int myParameter) 
{ 
    MyObject working_set = new MyObject(); 
    interim = working_set.doSomethingElse(myParameter); 
    another_interim = doSomethingSneaky(working_set); 
    return working_set.doSomethingElseAgain(another_interim); 
} 

Trừ khi bạn biết chắc chắn những gì đang xảy ra trong doSomethingSneaky(), bạn có thể có nhu cầu về đồng bộ hóa ở đâu đó. Cụ thể, bạn có thể phải đồng bộ hóa trên các thao tác trên working_setdoSomethingSneaky() có thể lưu trữ tham chiếu đến đối tượng địa phương working_set của bạn và chuyển giao cho một chủ đề khác trong khi bạn vẫn đang thực hiện công cụ theo phương pháp của mình hoặc trong phương thức của working_set. Ở đây bạn sẽ phải phòng thủ hơn.

Nếu, tất nhiên, bạn chỉ làm việc với các kiểu nguyên thủy, thậm chí gọi ra các phương thức khác, chuyển các giá trị đó cùng, sẽ không thành vấn đề.

+0

"bất kỳ loại tham chiếu nào" có thể là "bất kỳ loại tham chiếu _mutable_" nào ... đối tượng không thay đổi không phải là vấn đề. – ColinD

+0

Cảnh sát công bằng. Tôi sẽ thay đổi điều đó. –

0

Bạn không cần phải lo lắng về các biến cục bộ. Tuy nhiên, các biến cá thể là thứ cần quan tâm.

4

Các phương pháp chỉ sử dụng biến cục bộ bên trong, không bị bất kỳ vấn đề nào về luồng không?

Đúng trong một cảm giác rất đơn giản, nhưng cho phép một cách rõ ràng - Tôi nghĩ rằng điều này chỉ đúng nếu:

  • một phương pháp như vậy chỉ sử dụng biến cục bộ là nguyên thủy hoặc tham chiếu đến các trường hợp có thể thay đổi mà không thể nếu không được truy cập bên ngoài phương pháp bằng bất kỳ phương tiện nào khác.

  • phương thức như vậy chỉ gọi các phương thức an toàn chỉ.

Một số cách các quy tắc có thể bị vi phạm:

  • Một biến cục bộ có thể được khởi tạo để trỏ đến một đối tượng mà cũng có thể truy cập bên ngoài phương pháp này. Ví dụ, một biến địa phương có thể trỏ đến một singleton (Foo bar = Foo.getSingleton()).

  • Một cá thể cục bộ được tổ chức bởi biến cục bộ có thể "bị rò rỉ" nếu cá thể được chuyển làm đối số cho phương thức bên ngoài giữ tham chiếu đến cá thể.

  • Một lớp không có biến mẫu và chỉ có một phương thức duy nhất không có biến cục bộ vẫn có thể gọi phương thức tĩnh của một lớp khác không an toàn bằng luồng.

1

Câu hỏi này rất chung chung, vì vậy, vui lòng không mong đợi bất kỳ sự cụ thể nào từ câu trả lời của tôi.

1_ Chúng tôi cần cẩn thận hơn với các phương pháp tĩnh hơn so với phương pháp thể hiện.

2_ @Justmycorrectopinion là đúng, nhưng một số thuật ngữ ông mô tả cần phải được xây dựng hơn để hoàn hảo. (Ngay cả khi phương pháp tĩnh, chỉ hoạt động trên biến cục bộ, vẫn có khả năng điều kiện chủng tộc.)

3_ Đối với tôi, có những quy tắc đơn giản đã giúp tôi phân tích an toàn luồng.

Hiểu xem mỗi thành phần được đóng gói trong đó có thể chia sẻ được hay không. Vì vậy, giải pháp đơn giản nhất là giảm phạm vi của tất cả các biến và chỉ tăng phạm vi nếu hoàn toàn cần thiết và nếu thành phần thực hiện đột biến trên một đối tượng, thường không phải là chủ đề an toàn của nó.

4_ Sử dụng công cụ hỗ trợ để thực hiện phân tích mã tĩnh về an toàn luồng. (Ý tưởng có plugin kiểm tra).

5_ Không bao giờ sử dụng phương pháp tĩnh để thực hiện đột biến đối tượng. Nếu gọi biến tĩnh gây ra đột biến đối tượng thì nhà phát triển chỉ đang phá vỡ OOPS.

6_ Luôn đảm bảo an toàn cho chủ đề. Hãy nhớ rằng một số phương pháp có thể không cần phải được đồng bộ khi bạn phát triển, nhưng có thể làm cho luồng không an toàn rất dễ dàng.

7_ Cuối cùng nhưng có lẽ là điểm quan trọng nhất của tôi, hãy đảm bảo rằng hầu hết các đối tượng của bạn đều không thay đổi. Theo kinh nghiệm của tôi, hầu hết thời gian, tôi không bao giờ phải làm cho nhiều đối tượng của tôi có thể thay đổi được. (Trong trường hợp hiếm hoi khi trạng thái đối tượng cần được thay đổi, việc sao chép phòng thủ/Tạo đối tượng mới hầu như luôn tốt hơn.)

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