2012-04-13 15 views
5

Nếu tôi có mã được đồng bộ hóa này mà tôi muốn thay thế bằng các tác nhân không đồng bộ hóa, làm cách nào?điều gì sẽ là mã java "diễn viên" song song để thay thế đồng bộ hóa tiêu chuẩn bằng mã chủ đề

public synchronized int incrementAndGet() { 
    i = i + 1; 
    return i; 
} 

và tôi có một loạt các người sử dụng trong trang web nơi mà tôi cần phải trả lại mỗi một số incrementing ... làm thế nào tôi có thể thay thế mã với mã diễn viên mà không có sự đồng bộ như vậy, không có mã đồng bộ chặn. mà tôi đoán sẽ thenn có thể chạy nó trên multicores vv (không phải là mục đích của diễn viên?).

+2

Trường hợp sử dụng hoàn hảo cho đại lý Akka. – elbowich

Trả lời

3

Một diễn viên đơn giản gói i trong tình trạng nội bộ của mình:

case object Inc 

class IncrementingActor extends Actor { 
    var i = 0 

    protected def receive = { 
     case Inc => 
      i += 1 
      sender ! i 
    } 
} 

Và ngăn chặn việc sử dụng (bạn cần để có được incrementAndGet bằng cách nào đó):

import akka.pattern.ask 

def incrementAndGet() = 
    Await.result((incrementingActor ? Inc).mapTo[Int], 1 seconds) 

Mã này là: chậm, phức tạp và phi thành ngữ. Điều gì về AtomicInteger?

+0

chỉ là một vài câu hỏi về mã ở trên: – Jas

+0

Tôi không muốn sử dụng atomicinteger, tôi không muốn sử dụng đồng bộ hóa, internet có đầy đủ các diễn viên có thể thay thế mã đa luồng cũ bằng mã mới với diễn viên không đồng bộ hóa tôi đề nghị một ví dụ và tôi chỉ thấy rằng bạn nói với tôi rằng các diễn viên không giải quyết vấn đề !!! tôi vẫn phải làm Await.result hoặc AtomicInteger giống như viết đồng bộ !!! các diễn viên không giải quyết vấn đề của tôi sau đó phải không? (trong các ví dụ của tôi). (xin lỗi nếu tôi nghe có vẻ khó chịu nhất với các diễn viên là giải pháp ma thuật cho mã đa luồng đồng bộ, tôi chỉ thấy nó không phải!) – Jas

+1

Vấn đề là, với ví dụ mà bạn đã chọn, sử dụng AtomicInteger có lẽ là giải pháp tốt nhất. Và AtomicInteger cũng sử dụng so sánh và trao đổi khác với đồng bộ. –

3

Đồng thời là một miền rộng lớn với nhiều vấn đề và cạm bẫy. Không có một cách tiếp cận duy nhất có thể giải quyết tất cả các vấn đề và một chuyên gia đồng thời thực sự có thể kết hợp một số phương pháp để có được kết quả tốt nhất.

Hiện tại trên thế giới JVM, tôi không nghĩ có các lựa chọn thay thế tốt hơn các số nguyên nguyên tử để tăng bộ đếm, đặc biệt nếu tranh chấp rất cao.

Điều đó đang được nói, nếu bạn muốn sử dụng diễn viên, mẹo để có được hiệu suất và khả năng mở rộng là để tránh yêu cầu (?) hoạt động càng nhiều càng tốt. Sử dụng cho biết thay vào đó (!) và sau đó sinh lợi. Khi kết quả có sẵn, diễn viên sẽ nhận được nó và tiếp tục kiểm soát. Không có gì khối và hồ bơi thread có thể chăm sóc của các diễn viên khác trong thời gian có nghĩa là. Điều đó chỉ hoạt động nếu hầu hết mã của bạn là bên trong các diễn viên.

Bắt đầu với Thomas giải pháp, bạn có thể viết một cái gì đó như:

case object Inc 
case class Count(i) 

class IncrementingActor extends Actor { 
    var i = 0 
    protected def receive = { 
    case Inc => 
     i += 1 
     sender ! Count(i) 
    } 
} 

class FooActor(counter: ActorRef) extends Actor { 
    protected def receive = { 
    case DoSomething() => { 
     // Perform some work 
     counter ! Inc 
    } 
    case Count(i) => { 
     // Do something with the counter result 
    } 
    } 
} 
0

đồng bộ incrementing một bộ đếm (như trong incrementAndGet()) có rất ít lợi ích nếu bạn muốn sử dụng một diễn viên. Ẩn khỏi chế độ xem có thực sự đồng bộ hóa trong hộp thư cho diễn viên. Ngoài ra, lớp AtomicInteger hoạt động tốt trên kiến ​​trúc đa lõi.

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