2011-09-18 26 views
9

Nếu tôi muốn giữ một bộ đếm toàn cục (ví dụ: để đếm số lượng yêu cầu đến qua nhiều luồng), thì cách tốt nhất để làm trong java sẽ là sử dụng một int dễ bay hơi. Giả sử, clojure đang được sử dụng là có một cách tốt hơn (thông lượng tốt hơn) để làm gì?truy cập đồng bộ trong clojure

Trả lời

13

tôi sẽ làm điều này với một atom trong Clojure:

(def counter (atom 0N)) 

;; increment the counter 
(swap! counter inc) 

;; read the counter 
@counter 
=> 1 

này là hoàn toàn thread-an toàn, và hiệu suất cao đáng ngạc nhiên. Ngoài ra, vì nó sử dụng xử lý số abitrary chính xác Clojure, nó không phải là dễ bị tràn số nguyên trong cách mà một int dễ bay hơi có thể .....

+0

nó sẽ cung cấp thông lượng tốt hơn sau đó sử dụng một int không ổn định? nếu có, bất kỳ thông tin chi tiết nào về lý do/cách tốt hơn. – 142857

+1

Một nguyên tử sẽ chậm hơn một chút so với int bay hơi. Nhưng trừ khi bạn đếm hàng triệu sự kiện mỗi giây, sự khác biệt sẽ không đủ lớn để nhận ra. Và ở mức thông lượng đó, một int dễ bay hơi sẽ tràn trong chưa đầy một giờ ...... – mikera

+3

Trên Clojure 1.3, nó có thể tràn: '(hoán đổi! (Atom 9223372036854775807) inc)' ném một ngoại lệ tràn. Việc sửa chữa là sử dụng BigInts: '(hoán đổi! (Nguyên tử 9223372036854775807N) inc)' hoặc chức năng tự động quảng bá 'inc'' –

7

Xác định một bộ đếm toàn cầu như một agent

(def counter (agent 0)) 

để tăng giá trị chứa trong các đại lý bạn send một chức năng (trong trường hợp này inc) cho agent:

(send counter inc) 

để đọc giá trị hiện tại bạn có thể sử dụng deref hoặc @ macro trình đọc:

@counter ;; same as (deref counter) 

Đại lý chỉ là một trong một số loại tham chiếu có sẵn. Bạn có thể đọc thêm về những điều này trên trang web Clojure:

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