2010-07-29 18 views
18

Tôi có một danh sách liên kết samples:Là LinkedList thread-safe khi tôi truy cập nó với phiếu mua hàng và phiếu thăm dò ý kiến ​​độc quyền?

protected LinkedList<RawDataset> samples = new LinkedList<RawDataset>(); 

Tôi đang phụ thêm yếu tố vào danh sách trong thread 1 như thế này:

this.samples.offer(data); 

Và tôi lấy yếu tố từ nó trong một thread thứ hai như như vậy:

public RawDataset retrieveSample() { 
    return this.samples.poll(); 
} 

Điều này có được coi là an toàn không? Mặc dù chuỗi 1 và 2 đều đang sửa đổi danh sách nhưng chúng chỉ làm như vậy trên đầu hoặc đuôi của danh sách, phải không?

Nếu không ai có thể đưa tôi đến một lớp học trong API Java đi kèm với poll/offer và chắc chắn là an toàn chỉ?

Cảm ơn bạn trước.

BTW: Collections.synchronizedList(new LinkedList()) sẽ không cấp cho tôi quyền truy cập vào offer/poll.

+1

Phương pháp 'offer' và' poll' thực sự declard trong giao diện 'Queue', được thực hiện bởi LinkedList ngoài các giao diện Danh sách. Đó là lý do tại sao các phương thức này không có sẵn trên kết quả từ Collections.synchronizedList. –

Trả lời

31

LinkedList không phải là chuỗi an toàn. Bạn sẽ phải tự mình khóa.

Hãy thử ConcurrentLinkedQueue hoặc LinkedBlockingDeque thay vào đó nếu nó phù hợp với nhu cầu của bạn, chúng là chuỗi an toàn nhưng có hành vi hơi khác so với LinkedList.

+0

Tôi nên làm gì, nếu tôi muốn có một hàng đợi có kích thước tối đa, để nếu một mục mới được chèn vào và chúng tôi đạt đến giá trị tối đa, mục cũ nhất sẽ bị xóa (không chặn, vì không cần thiết)? Tôi cần nó cho một bản ghi của các sự kiện X cuối cùng. Tôi có nên sử dụng LinkedList bình thường và sử dụng "đồng bộ" trên đó không? Hoặc là có một cấu trúc dữ liệu đồng thời tốt đẹp cho điều này? –

+0

@androiddeveloper Điều đó nghe có vẻ giống như một hàng đợi hình tròn, bạn nên đặt một câu hỏi ở đây trên stackoverflow về việc không thêm nhận xét vào câu hỏi cũ này. – nos

+0

Có, tôi có cảm giác đây là tên của nó, nhưng có một cài đặt được xây dựng cho điều này, đó là an toàn chỉ? –

8

nếu bạn có JDK, bạn có thể xem mã nguồn của "Collections.synchronizedList()". Nó rất đơn giản, vì vậy bạn có thể tạo một bản sao của phương thức này để có được cả LinkedList và các chức năng đồng bộ hóa.

public class SynchronizedLinkedList<T> implements List<T> { 

    private LinkedList<T> list; 

    private Object lock; 

    public void add(T object) { 
     synchronized(lock) { 
      list.add(object); 
     } 
    } 

    // etc. 
} 
+2

Tôi thường có khuynh hướng thích các lớp hiện có hơn việc triển khai các lớp học của riêng tôi. Vì vậy, tôi sẽ đi với một trong hai đề xuất khác. Nhưng cảm ơn bạn anyway. –

+6

Tại sao bạn giới thiệu một đối tượng khóa bổ sung nếu bạn có thể đơn giản đồng bộ hóa trên đối tượng có thể thay đổi — danh sách — chính nó? –

1

Điều đó đúng - LinkedList không được đồng bộ hóa và do đó không an toàn. Nếu bạn không muốn sử dụng các loại suy đồng bộ mới hơn của LinkedList, cụ thể là, ConcurrentLinkedQueue hoặc LinkedBlockingQueue, bạn có thể khởi tạo LinkedList như thế này:

LinkedList<RawDataset> samples = (LinkedList)Collections.synchronizedList(new LinkedList<RawDataset>()); 
+4

Điều này có thể hoạt động trong một số môi trường, nhưng không đảm bảo rằng giá trị được trả lại từ 'Bộ sưu tập.syncList() 'luôn luôn có thể được đúc thành một' LinkedList'. Nói chung, nếu bạn phải truyền, bạn cần suy nghĩ lại về thiết kế của mình. –

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