2012-03-12 24 views
7

Hi guys: Các tài liệu cho clojure "nguyên tử" khẳng định rằng -điều kiện Race và Atoms clojure

"Changes to atoms are always free of race conditions." 

However- một điều kiện chủng tộc được xác định không chỉ về một sự thay đổi, nhưng thay vào đó, trong bối cảnh các phép toán logic song song trong các luồng khác nhau.

Tôi tự hỏi - ý nghĩa của việc đảm bảo rằng "Các thay đổi đối với nguyên tử luôn miễn là điều kiện chủng tộc"? Trong java, chúng tôi có nguyên thủy nguyên tử, hỗ trợ một số hoạt động an toàn chủ đề cụ thể (ví dụ, AtomicInteger hỗ trợ một hoạt động "getAndIncrement"). Nhưng nguyên tử Clojure là loại-agnostic, ví dụ, chúng ta có thể gọi:

(atom "Hi im a string") Or 
    (atom (.getClass Object)) 

Tính linh hoạt của phương pháp nguyên tử có nghĩa là Clojure, dưới mui xe, không phải là "thông minh" cung cấp loại cụ thể nguyên tử/thread-safe hoạt động cho các nguyên tử.

Vì vậy, tôi sẽ hỏi - những gì chính xác là phương pháp nguyên tử "làm" với các đối tượng của chúng tôi

Trả lời

11

Một atom là một cách hiệu quả một vị trí lưu trữ nguyên tử được đảm bảo (tức là nó chỉ đơn giản là đồng bộ hóa toàn bộ đối tượng?) là chủ đề an toàn.

Nguyên tử tương tự như kiểu dữ liệu nguyên tử của Java (như AtomicReference), nhưng thực sự có phần mạnh hơn vì nguyên tử cho phép bạn sử dụng hàm tùy ý để cập nhật nguyên tử. Ví dụ:

(def a (atom "foo")) 

(defn appender [x] 
    "Higher order function that returns a function which appends a specific string" 
    (fn [s] 
    (str s x))) 

(swap! a (appender "bar")) 
=> "foobar" 

Trong ví dụ trên, các hoạt động swap! xử nguyên tử, mặc dù hoạt động appender chúng tôi đang đi để nó có khả năng có thể là một chức năng khá phức tạp. Trong thực tế, các nguyên tử cho phép bạn sử dụng một hoạt động cập nhật tùy ý theo cách nguyên tử (bạn thường nên dính vào các hàm thuần túy vì có thể gọi hàm nhiều lần trong trường hợp tranh chấp).

Nguyên tử rõ ràng không đảm bảo an toàn chủ đề của các đối tượng bạn đặt bên trong chúng (ví dụ: nếu bạn đặt một ArrayList Java không đồng bộ bên trong, thì vẫn không an toàn để sử dụng đồng thời). Tuy nhiên nếu bạn dính vào các kiểu dữ liệu bất biến của Clojure, tất cả đều hoàn toàn an toàn thì bạn sẽ tốt.

+5

* "Các chức năng này được đảm bảo sẽ được thực thi tuần tự" * - đây không phải là những gì 'nguyên tử' đảm bảo. Sự đảm bảo thực tế là 'swap af' nhớ giá trị của' a', chuyển nó tới 'f' và nếu giá trị' a' sau 'f' được hoàn thành vẫn bằng giá trị cũ, sau đó nó được thay thế bằng kết quả của 'f'. Nhiều chức năng khác có thể đã được áp dụng cho 'a' trong thời gian chờ đợi, miễn là hiệu ứng của chúng bị hủy bỏ. –

+1

@Rafal - cảm ơn vị trí tốt, tôi đã cập nhật câu trả lời chính xác hơn một chút. – mikera

+0

@myself: So sánh cơ bản thực sự là Java == (nhận dạng đối tượng), vì vậy thay vì "bằng nhau" tôi nên viết 'giống hệt' và thay vì "hủy bỏ lẫn nhau" -> "để nguyên tử tham chiếu cùng một đối tượng" . –

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