2012-07-26 26 views
5

Đây là kịch bản của tôi:Phương thức Akka onReceive có thực hiện đồng thời không?

Tôi có một diễn viên chính, nhận được tin nhắn từ nhiều diễn viên con. Các thông báo này chứa dữ liệu được tổng hợp. Trong logic tổng hợp này, tôi có cần xử lý các vấn đề đồng bộ hóa không, nếu tôi sử dụng cấu trúc dữ liệu được chia sẻ để thu thập tập hợp?

else if(arg0 instanceof ReducedMsg){ 

          ReducedMsg reduced = (ReducedMsg)arg0; 
     counter.decrementAndGet(); 

     synchronized(finalResult){ 

      finalResult.add((KeyValue<K, V>) reduced.getReduced()); 

      if(counter.get() == 0){ 
            if(checkAndReduce(finalResult)){ 

        finalResult.clear(); 
       } 
       else{ 
        stop(); 
        latch.countDown(); 
       } 

      } 

     } 



    } 

Vì vậy, bạn có thể thấy tôi có finalResult, mà mỗi thông điệp sẽ được tổng hợp và sau khi xử lý logic, bộ sưu tập cũng cần được xóa.

Thực ra những gì tôi đang cố gắng triển khai là bản đồ giảm bớt đệ quy (liên kết) đệ quy. Vì vậy, tôi cần phải giữ khối đồng bộ tôi giả sử? Hoặc là do bất kỳ cơ hội nào Akka thực hiện onReceive một luồng tại một thời điểm?

Logic này tạo kết quả chính xác và có thể dự đoán được về tập dữ liệu nhỏ. Vấn đề của tôi là khi tập dữ liệu đầu vào của tôi lớn một chút, mã bị treo. Tôi muốn chắc chắn đó là vì bối cảnh chuyển đổi cho khối đồng bộ hóa của tôi, để tôi có thể chia thành một thiết kế khác.

Trả lời

14

onReceive()không bao giờ gọi đồng thời. Đây là sự bảo đảm cơ bản nhất mà Akka mang lại cho bạn.

Điều này có nghĩa rằng nếu biến counter của bạn là một lĩnh vực trong một diễn viên và không có đoạn mã khác có thể truy cập vào lĩnh vực trực tiếp, bạn có thể yên tâm sử dụng bình thường int/long thay vì AtomicInteger/AtomicLong. Đồng bộ hóa trên finalResult là không cần thiết giả định nó là một trường được đóng gói và ẩn trong một diễn viên.

Cuối cùng việc sử dụng CountDownLatch là đáng ngờ. Trong các ứng dụng Akka, bạn không nên sử dụng bất kỳ đồng bộ hóa nguyên thủy nào. Các diễn viên chủ yếu là một luồng đơn và tất cả các giao tiếp (bao gồm cả việc thức dậy và truyền dữ liệu) nên được thực hiện thông qua việc truyền thông điệp.

Điều này được giải thích trong tài liệu: http://doc.akka.io/docs/akka/2.0.2/general/jmm.html#Actors_and_the_Java_Memory_Model

+0

Cảm ơn bạn Tomasz. Dòng đầu tiên của bạn xóa nhiều nghi ngờ của tôi! Regd việc sử dụng các chốt, tôi phải làm điều đó để cung cấp cho một giao diện khách hàng mà nên chờ đợi cho đến khi việc xử lý diễn viên được hoàn thành. Mục tiêu của tôi là phát triển một khung công tác java, trong đó nội bộ sẽ sử dụng Akka/Scala để xử lý. –

+0

@sutanudalui: bạn có thể gọi diễn viên * đồng bộ *, về cơ bản có nghĩa là Akka sẽ chờ phản hồi trên một số hàng đợi tạm thời. Không cần phải làm điều này bằng tay. Tham khảo tài liệu của Akka về mẫu 'ask' (trái ngược với' tell'). –

+0

OK. Tôi sẽ sâu hơn một chút. Tôi có một bộ định tuyến robin tròn với các diễn viên N nô lệ. Điều tôi định làm là xử lý song song và sau đó tích lũy kết quả. Vì vậy, các diễn viên tổng thể, nhận được mỗi đầu vào, các tuyến đường đến một trong những nô lệ. Các nô lệ, khi xử lý tin nhắn, nhắn tin lại cho chủ nhân phải tổng hợp. Giai đoạn tập hợp này, nơi tôi đã suy nghĩ về các vấn đề đồng bộ hóa. Từ liên kết doc được cung cấp, tôi thấy rằng Akka không thể gurantee (cũng không ai có thể đoán được!) Mà chia sẻ bộ nhớ, trong trường hợp của tôi, "finalResult" sẽ được bảo vệ. Tôi có hiểu chính xác điều này không? –

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