2010-05-21 14 views
5

sử dụng một java.nio phải đăng ký quan tâm đến hoạt động thông qua SelectableChannel:nio Best Practices - SelectableChannel và InterestOps

SelectionKey = SelectableChannel.register(selector, interestInOpsBitmask) 

Đăng ký Lãi suất:

  • ghi đè SelectionKey hiện bằng cách thực hiện SelectableChannel.register với Ops mới
  • VS. cập nhật SelectionKey hiện với key.interestOps (key.interestOps() | newOp)

Đang hủy đăng ký Lãi suất:

  • SelectionKey.cancel và SelectableChannel.register với Ops mới
  • VS. cập nhật SelectionKey hiện tại như trên

Có bất kỳ ưu điểm nào & không?

Cảm ơn

Trả lời

3

Nếu bạn luôn gửi bản thực thi đến một nhóm luồng sau khi chọn() trả về, bạn có thể muốn hủy khóa ngay lập tức, vì bạn mất quyền kiểm soát thời gian Runnable sẽ thực hiện.

Ví dụ: Nếu bạn thực hiện lựa chọn tiếp theo() trước khi hủy khóa trước (chuỗi vẫn đang chờ thực thi), nó sẽ hợp lệ, khiến một luồng khác mang khóa đã được gửi đi. Nếu một trong các chủ đề này hủy khóa, người khác sẽ nhận được CancelledKeyException ngoài việc giới thiệu hành vi không mong muốn.

Ngay cả khi bạn hủy khóa, chủ đề có thể đăng ký cùng một kênh (cập nhật các phím chọn) trước khi kênh trở thành chưa đăng ký (do trước đó key.cancel()). Điều gì, một lần nữa, sẽ gây ra một CancelledKeyException.

Để thoát khỏi cái bẫy này, bạn có thể muốn để xử lý các sự kiện luôn trong vòng lặp tiếp theo:

while (true) { // true or something less risky 
    //for each pendingTasks call 
    pool.execute(task); 
    Iterator<SelectionKey> iter = selector.selectedKeys().iterator(); 
    while (iter.hasNext()) { 
     SelectionKey key = iter.next(); 
     iter.remove(); 
     key.cancel(); 
     //store dispatch for the next while iteration 
     pendingTasks.add(task); // do not execute tasks before next select() 
    } 
    selector.select(TIMEOUT); // or selectNow if there are 
           //any pending events to handle. 
} 

thực hiện firt sẽ, gần như, không bao giờ quay trở lại chìa khóa, nhưng chọn() ở phần cuối của bạn loop MAY đảm bảo rằng kênh đã hủy không được đăng ký (chịu sự cố của bạn) từ bộ chọn.

Tuy nhiên, nếu bạn chỉ thực hiện nhiệm vụ trong cùng một chuỗi bạn nghe các sự kiện chọn của bạn, hãy cập nhật âm thanh dễ dàng và an toàn hơn.

+0

bạn sẽ thay đổi thời gian chờ của bộ chọn nếu có các tác vụ vẫn đang chạy trên nhóm chủ đề của bạn.Nếu bạn sử dụng một thời gian chờ lớn trong lựa chọn của bạn() bạn có thể gây ra các chủ đề bị chặn cho việc đăng ký kênh mới/hiện tại để chọn. – paulosuzart

3

Tôi sẽ cập nhật sở thích hiện tại bằng cách sử dụng toán tử hoặc toán tử như bạn đề xuất. Tôi sẽ lo lắng về việc thiếu các lựa chọn nếu tôi (tạm thời) hủy bỏ khóa lựa chọn.

Bên cạnh đó, hủy + đăng ký lại có vẻ phức tạp hơn việc cập nhật.

Trừ khi bạn có lý do logic hợp lý để đăng ký với các ops mới, tôi khuyên bạn nên luôn cập nhật.