Đầu tiên tôi xin nói rằng tôi có khá nhiều kinh nghiệm về Java, nhưng chỉ gần đây mới quan tâm đến các ngôn ngữ chức năng. Gần đây tôi đã bắt đầu xem xét Scala, nó có vẻ như là một ngôn ngữ rất hay.
Tuy nhiên, tôi đã đọc về khung Diễn viên của Scala trong Lập trình trong Scala , và có một điều tôi không hiểu. Trong chương 30.4, nó nói rằng sử dụng react
thay vì receive
làm cho nó có thể sử dụng lại các luồng, điều này tốt cho hiệu suất, vì các luồng rất đắt trong JVM.
Điều này có nghĩa là, miễn là tôi nhớ gọi react
thay vì receive
tôi có thể bắt đầu bao nhiêu Diễn viên tùy thích? Trước khi khám phá ra Scala, tôi đã chơi với Erlang và tác giả của Lập trình Erlang tự hào về việc tạo ra hơn 200.000 quy trình mà không tốn một giọt mồ hôi. Tôi không muốn làm điều đó với các luồng Java. Tôi đang xem những giới hạn nào trong Scala so với Erlang (và Java)?
Ngoài ra, việc tái sử dụng luồng này hoạt động như thế nào trong Scala? Hãy giả sử, vì đơn giản, tôi chỉ có một luồng. Liệu tất cả các tác nhân mà tôi bắt đầu chạy tuần tự trong chuỗi này, hay một số loại chuyển đổi tác vụ sẽ diễn ra? Ví dụ: nếu tôi bắt đầu hai diễn viên bóng bàn nhắn tin cho nhau, liệu tôi có gặp nguy cơ bế tắc nếu họ bắt đầu trong cùng một chủ đề không?
Theo Lập trình trong Scala , viết các diễn viên để sử dụng react
khó hơn với receive
. Điều này nghe có vẻ hợp lý, vì react
nó không quay trở lại. Tuy nhiên, cuốn sách tiếp tục chỉ ra cách bạn có thể đặt react
một vòng lặp bên trong bằng cách sử dụng Actor.loop
. Kết quả là, bạn nhận được
loop {
react {
...
}
}
mà đối với tôi, có vẻ khá giống với
while (true) {
receive {
...
}
}
được sử dụng trước đó trong cuốn sách. Tuy nhiên, cuốn sách nói rằng "trong thực tế, các chương trình sẽ cần ít nhất một vài receive
". Vậy tôi còn thiếu gì ở đây? Điều gì có thể receive
làm mà react
không thể, ngoài việc trở lại? Và tại sao tôi lại quan tâm?
Cuối cùng, đi đến cốt lõi của những gì tôi không hiểu: cuốn sách tiếp tục đề cập đến cách sử dụng react
làm cho nó có thể loại bỏ ngăn xếp cuộc gọi để sử dụng lại chuỗi. Nó hoạt động như thế nào? Tại sao cần loại bỏ ngăn xếp cuộc gọi? Và tại sao ngăn xếp cuộc gọi có thể bị loại bỏ khi một hàm kết thúc bằng cách ném một ngoại lệ ( react
), nhưng không phải khi nó kết thúc bằng cách trả về ( receive
)?
Tôi có ấn tượng rằng Lập trình trong Scala đã đề cập đến một số vấn đề chính ở đây, điều này thật đáng tiếc, bởi vì nếu không thì đây là một cuốn sách thực sự xuất sắc.