2013-02-09 17 views
7

Từ Java Concurrency in practice Chương 3.3.3. ThreadLocalLời khuyên về việc sử dụng ThreadLocals để bọc các đối tượng đơn lẻ có thể thay đổi

biến Thread-địa phương thường được sử dụng để ngăn chặn việc chia sẻ trong các thiết kế dựa trên Singletons có thể thay đổi hoặc biến toàn cục.

Nếu chúng ta quấn chàng Singleton có thể thay đổi trong ThreadLocal mỗi chuỗi sẽ có bản sao Singleton riêng? Làm thế nào nó sẽ vẫn là một singleton sau đó? Đây có phải là những gì các tác giả có nghĩa là hoặc tôi thiếu một cái gì đó khá rõ ràng ở đây?

Trả lời

2

Nếu chúng ta quấn chàng Singleton có thể thay đổi trong một ThreadLocal

AFAIK bạn không quấn lớp singleton với ThreadLocal, nhưng đối tượng chứa trong singleton là có thể thay đổi hoặc không an toàn. Như ví dụ thảo luận chính xác rằng kết nối JDBC JDBC không phải là chủ đề an toàn và sẽ yêu cầu bảo vệ bổ sung, do đó làm tăng tranh chấp.

Vì vậy, trong trường hợp Singletons được sử dụng chỉ với mục đích chia sẻ, thì thay thế những thứ đó bằng ThreadLocal là một ý tưởng hay, vì tất cả các chủ đề đều có kết nối riêng và không cần bảo vệ thêm.

khác ví dụ tốt về trường hợp sử dụng ThreadLocal là Random hệ, nếu có một đối tượng duy nhất Random sau đó là tranh chấp trong chủ đề cho "hạt giống" , vì vậy nếu mỗi thread có đối tượng ngẫu nhiên của riêng mình sau đó không có tranh chấp nữa và điều đó có ý nghĩa.

+0

Ý bạn là gì bởi "bạn không quấn lớp đơn với ThreadLocal, nhưng đối tượng chứa trong singleton có thể ẩn hoặc không an toàn". bạn có thể xây dựng được không? – Geek

+0

Tôi có nghĩa là singleton là một container mà bạn sử dụng để chia sẻ đối tượng. Giống như một singleton ConnectionManager sẽ được sử dụng để chia sẻ đối tượng kết nối DB. Vì vậy, bạn không quấn Trình quản lý kết nối mà thay vào đó là kết nối trong ThreadLocal (Thread Confinement) và do đó tạo kết nối có thể thay đổi và không an toàn, an toàn. Tôi hy vọng nó có ý nghĩa. –

+0

vâng, điều đó có ý nghĩa. Tôi nghĩ rằng trích dẫn trong cuốn sách là mơ hồ. Bạn nghĩ sao ? – Geek

0

Nếu bạn bọc một Singleton (như là một mẫu thiết kế) trong một ThreadLocal nó sẽ vẫn là một Singleton. Không có phép thuật lớn trong ThreadLocal, nếu bạn kiểm tra nguồn của ThreadLocal bạn vừa thấy nó. Nó sử dụng một Bản đồ và sử dụng luồng hiện tại làm khóa. Vì vậy, nó là khá vô dụng để đặt một Singleton (một thực hiện tốt) trong một ThreadLocal. Vì bạn chỉ nhận được Singleton giống nhau theo nhiều cách khác nhau.

Tôi cho rằng tác giả có nghĩa là nếu thiết kế của bạn sử dụng Singletons và/hoặc biến toàn cầu, ThreadLocal là một lựa chọn tốt nếu bạn cần một thứ gì đó duy nhất cho mỗi chuỗi và không muốn chuyển tất cả xuống phân cấp cuộc gọi. Nhưng điều này khác với Singleton. Tất nhiên bạn có thể có một ThreadLocal gói gọn trong Singleton của bạn vì vậy nó sẽ có một số trạng thái cụ thể chủ đề (nhưng mà tôi sẽ không gọi một Singleton nữa)

0

những gì tôi hiểu với dòng này là khi ứng dụng được thiết kế theo cách mà một lớp Singleton có trạng thái có thể thay đổi được đọc và viết bởi nhiều luồng sẽ yêu cầu an toàn chủ đề, do đó bạn cần serialize tất cả quyền truy cập vào đó tiểu bang. Bạn có thể xem xét việc tạo một ThreadLocal trên singleton có thể thay đổi đó. (từ cuốn sách :-) Ví dụ, một ứng dụng đơn luồng có thể duy trì một kết nối cơ sở dữ liệu toàn cầu được khởi tạo lúc khởi động để tránh phải chuyển một kết nối tới mọi phương thức. Vì các kết nối JDBC có thể không an toàn luồng, một ứng dụng đa luồng sử dụng kết nối toàn cục mà không có sự phối hợp bổ sung cũng không an toàn. Bằng cách sử dụng một ThreadLocal để lưu trữ kết nối JDBC, như trong ConnectionHolder trong Liệt kê 3.10, mỗi luồng sẽ có kết nối riêng của nó.

private static ThreadLocal<Connection> connectionHolder= new ThreadLocal<Connection>() { 
     public Connection initialValue() { 
    return DriverManager.getConnection(DB_URL); 
    } 
}; 
    public static Connection getConnection() { 
    return connectionHolder.get(); 
    } 
Các vấn đề liên quan