Tidak, metode tidak perlu disinkronkan, dan Anda tidak perlu menentukan metode apa pun; mereka sudah ada di ConcurrentLinkedQueue, gunakan saja. ConcurrentLinkedQueue melakukan semua operasi penguncian dan lainnya yang Anda butuhkan secara internal; produser Anda menambahkan data ke antrian, dan konsumen Anda melakukan polling untuk itu.
Pertama, buat antrian Anda:
Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();
Sekarang, di mana pun Anda membuat objek producer / consumer, teruskan antrian sehingga mereka memiliki tempat untuk meletakkan objek mereka (Anda dapat menggunakan setter untuk ini, sebagai gantinya, tetapi saya lebih suka melakukan hal semacam ini dalam konstruktor):
YourProducer producer = new YourProducer(queue);
dan:
YourConsumer consumer = new YourConsumer(queue);
dan menambahkan barang ke dalamnya di produser Anda:
queue.offer(myObject);
dan mengambil barang di konsumen Anda (jika antrian kosong, poll () akan mengembalikan null, jadi periksa):
YourObject myObject = queue.poll();
Untuk info lebih lanjut lihat Javadoc
EDIT:
Jika Anda perlu memblokir menunggu antrian tidak kosong, Anda mungkin ingin menggunakan LinkedBlockingQueue , dan gunakan metode take (). Namun, LinkedBlockingQueue memiliki kapasitas maksimum (default ke Integer.MAX_VALUE, yang lebih dari dua miliar) dan dengan demikian mungkin atau mungkin tidak sesuai tergantung pada keadaan Anda.
Jika Anda hanya memiliki satu utas yang memasukkan barang ke antrean, dan utas lain mengambil barang dari antrean, ConcurrentLinkedQueue mungkin berlebihan. Lebih dari itu ketika Anda mungkin memiliki ratusan atau bahkan ribuan utas yang mengakses antrian pada saat yang bersamaan. Kebutuhan Anda mungkin akan dipenuhi dengan menggunakan:
Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());
Nilai plusnya adalah ia mengunci instans (antrian), sehingga Anda dapat menyinkronkan antrian untuk memastikan atomicity operasi gabungan (seperti dijelaskan oleh Jared). Anda TIDAK DAPAT melakukan ini dengan ConcurrentLinkedQueue, karena semua operasi dilakukan TANPA mengunci instance (menggunakan variabel java.util.concurrent.atomic). Anda TIDAK perlu melakukan ini jika Anda ingin memblokir saat antrian kosong, karena poll () hanya akan mengembalikan null saat antrian kosong, dan poll () adalah atom. Periksa untuk melihat apakah poll () mengembalikan null. Jika ya, tunggu (), lalu coba lagi. Tidak perlu dikunci.
Akhirnya:
Sejujurnya, saya baru saja menggunakan LinkedBlockingQueue. Ini masih berlebihan untuk aplikasi Anda, tetapi kemungkinan besar itu akan berfungsi dengan baik. Jika kinerjanya tidak cukup (PROFIL!), Anda selalu dapat mencoba yang lain, dan itu berarti Anda tidak perlu berurusan dengan hal-hal yang disinkronkan:
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.
Yang lainnya sama. Put mungkin tidak akan memblokir, karena Anda tidak mungkin memasukkan dua miliar objek ke dalam antrean.