Không, các phương thức không cần đồng bộ và bạn không cần xác định bất kỳ phương thức nào; chúng đã có trong ConcurrentLinkedQueue, chỉ cần sử dụng chúng. ConcurrentLinkedQueue thực hiện tất cả các thao tác khóa và các thao tác khác mà bạn cần trong nội bộ; (các) nhà sản xuất của bạn thêm dữ liệu vào hàng đợi và người tiêu dùng của bạn thăm dò ý kiến đó.
Đầu tiên, hãy tạo hàng đợi của bạn:
Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();
Bây giờ, bất cứ nơi nào bạn đang tạo các đối tượng nhà sản xuất / người tiêu dùng của mình, hãy chuyển vào hàng đợi để họ có một nơi nào đó để đặt các đối tượng của mình (thay vào đó, bạn có thể sử dụng một setter cho việc này, nhưng tôi thích làm kiểu này hơn trong một constructor):
YourProducer producer = new YourProducer(queue);
và:
YourConsumer consumer = new YourConsumer(queue);
và thêm nội dung vào đó trong trình sản xuất của bạn:
queue.offer(myObject);
và lấy những thứ trong người tiêu dùng của bạn (nếu hàng đợi trống, thăm dò ý kiến () sẽ trả về null, vì vậy hãy kiểm tra nó):
YourObject myObject = queue.poll();
Để biết thêm thông tin, hãy xem Javadoc
BIÊN TẬP:
Nếu bạn cần chặn chờ đợi hàng đợi không bị trống, bạn có thể muốn sử dụng LinkedBlockingQueue và sử dụng phương thức take (). Tuy nhiên, LinkedBlockingQueue có dung lượng tối đa (mặc định là Integer.MAX_VALUE, là hơn hai tỷ) và do đó có thể thích hợp hoặc không tùy thuộc vào hoàn cảnh của bạn.
Nếu bạn chỉ có một luồng đưa thứ vào hàng đợi và một luồng khác đưa thứ ra khỏi hàng đợi, ConcurrentLinkedQueue có thể là quá mức cần thiết. Nó nhiều hơn khi bạn có thể có hàng trăm hoặc thậm chí hàng nghìn luồng truy cập hàng đợi cùng một lúc. Nhu cầu của bạn có thể sẽ được đáp ứng bằng cách sử dụng:
Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());
Một điểm cộng của điều này là nó khóa trên cá thể (hàng đợi), vì vậy bạn có thể đồng bộ hóa trên hàng đợi để đảm bảo tính nguyên tử của các hoạt động tổng hợp (như Jared giải thích). Bạn KHÔNG THỂ làm điều này với ConcurrentLinkedQueue, vì tất cả các hoạt động được thực hiện mà KHÔNG khóa trên phiên bản (sử dụng các biến java.util.concurrent.atomic). Bạn sẽ KHÔNG cần phải làm điều này nếu bạn muốn chặn khi hàng đợi trống, bởi vì thăm dò ý kiến () sẽ chỉ trả về null trong khi hàng đợi trống và thăm dò ý kiến () là nguyên tử. Kiểm tra xem thăm dò ý kiến () trả về null. Nếu có, hãy đợi (), sau đó thử lại. Không cần khóa.
Cuối cùng:
Thành thật mà nói, tôi chỉ muốn sử dụng một LinkedBlockingQueue. Nó vẫn còn quá mức cần thiết cho ứng dụng của bạn, nhưng tỷ lệ cược là nó sẽ hoạt động tốt. Nếu nó không đủ hiệu quả (PROFILE!), Bạn luôn có thể thử một cái gì đó khác và điều đó có nghĩa là bạn không phải xử lý BẤT KỲ nội dung đồng bộ nào:
BlockingQueue<YourObject> queue = new LinkedBlockingQueue<YourObject>();
queue.put(myObject); // Blocks until queue isn't full.
YourObject myObject = queue.take(); // Blocks until queue isn't empty.
Mọi thứ khác là như nhau. Đặt có thể sẽ không chặn, bởi vì bạn không có khả năng đưa hai tỷ đối tượng vào hàng đợi.