Karena tidak ada jawaban yang ditandai sebagai jawaban yang diterima, saya telah berupaya membuat contoh kunci langsung;
Program asli ditulis oleh saya pada bulan April 2012 untuk mempelajari berbagai konsep multithreading. Kali ini saya telah memodifikasinya untuk membuat jalan buntu, kondisi balapan, livelock dll.
Jadi mari kita memahami pernyataan masalah terlebih dahulu;
Masalah Pembuat Cookie
Ada beberapa wadah bahan: ChocoPowederContainer , WheatPowderContainer .CookieMaker mengambil sejumlah bubuk dari wadah bahan untuk membuat kue . Jika pembuat kue menemukan wadah kosong, ia memeriksa wadah lain untuk menghemat waktu. Dan menunggu sampai Filler mengisi wadah yang diperlukan. Ada Pengisi yang memeriksa wadah pada interval reguler dan mengisi jumlah tertentu jika wadah membutuhkannya.
Silakan periksa kode lengkap di github ;
Biarkan saya menjelaskan implementasi Anda secara singkat.
- Saya memulai Filler sebagai utas daemon. Jadi itu akan tetap mengisi wadah secara berkala. Untuk mengisi wadah pertama, ia mengunci wadah -> memeriksa apakah perlu bubuk -> mengisinya -> memberi sinyal semua pembuat yang menunggu -> membuka kunci wadah.
- Saya buat CookieMaker dan mengatur bahwa itu dapat memanggang hingga 8 cookie secara paralel. Dan saya mulai 8 utas untuk memanggang kue.
- Setiap thread pembuat membuat 2 sub-thread yang dapat dipanggil untuk mengambil bubuk dari wadah.
- Sub-thread mengambil kunci pada wadah dan memeriksa apakah itu memiliki cukup bubuk. Jika tidak, tunggu beberapa saat. Setelah Filler mengisi wadah, ia mengambil bubuk, dan membuka kunci wadah.
- Sekarang melengkapi kegiatan lain seperti: membuat campuran dan memanggang dll.
Mari kita lihat kodenya:
CookieMaker.java
private Integer getMaterial(final Ingredient ingredient) throws Exception{
:
container.lock();
while (!container.getIngredient(quantity)) {
container.empty.await(1000, TimeUnit.MILLISECONDS);
//Thread.sleep(500); //For deadlock
}
container.unlock();
:
}
IngredientContainer.java
public boolean getIngredient(int n) throws Exception {
:
lock();
if (quantityHeld >= n) {
TimeUnit.SECONDS.sleep(2);
quantityHeld -= n;
unlock();
return true;
}
unlock();
return false;
}
Semuanya berjalan dengan baik sampai Filler mengisi wadah. Tetapi jika saya lupa untuk memulai pengisi, atau pengisi pergi cuti yang tak terduga, sub-utas terus mengubah negara mereka untuk memungkinkan pembuat lain untuk pergi dan memeriksa wadah.
Saya juga telah membuat daemon ThreadTracer yang terus memantau status utas dan kebuntuan. Ini keluaran dari konsol;
2016-09-12 21:31:45.065 :: [Maker_0:WAITING, Maker_1:WAITING, Maker_2:WAITING, Maker_3:WAITING, Maker_4:WAITING, Maker_5:WAITING, Maker_6:WAITING, Maker_7:WAITING, pool-7-thread-1:TIMED_WAITING, pool-7-thread-2:TIMED_WAITING, pool-8-thread-1:TIMED_WAITING, pool-8-thread-2:TIMED_WAITING, pool-6-thread-1:TIMED_WAITING, pool-6-thread-2:TIMED_WAITING, pool-5-thread-1:TIMED_WAITING, pool-5-thread-2:TIMED_WAITING, pool-1-thread-1:TIMED_WAITING, pool-3-thread-1:TIMED_WAITING, pool-2-thread-1:TIMED_WAITING, pool-1-thread-2:TIMED_WAITING, pool-4-thread-1:TIMED_WAITING, pool-4-thread-2:RUNNABLE, pool-3-thread-2:TIMED_WAITING, pool-2-thread-2:TIMED_WAITING]
2016-09-12 21:31:45.065 :: [Maker_0:WAITING, Maker_1:WAITING, Maker_2:WAITING, Maker_3:WAITING, Maker_4:WAITING, Maker_5:WAITING, Maker_6:WAITING, Maker_7:WAITING, pool-7-thread-1:TIMED_WAITING, pool-7-thread-2:TIMED_WAITING, pool-8-thread-1:TIMED_WAITING, pool-8-thread-2:TIMED_WAITING, pool-6-thread-1:TIMED_WAITING, pool-6-thread-2:TIMED_WAITING, pool-5-thread-1:TIMED_WAITING, pool-5-thread-2:TIMED_WAITING, pool-1-thread-1:TIMED_WAITING, pool-3-thread-1:TIMED_WAITING, pool-2-thread-1:TIMED_WAITING, pool-1-thread-2:TIMED_WAITING, pool-4-thread-1:TIMED_WAITING, pool-4-thread-2:TIMED_WAITING, pool-3-thread-2:TIMED_WAITING, pool-2-thread-2:TIMED_WAITING]
WheatPowder Container has 0 only.
2016-09-12 21:31:45.082 :: [Maker_0:WAITING, Maker_1:WAITING, Maker_2:WAITING, Maker_3:WAITING, Maker_4:WAITING, Maker_5:WAITING, Maker_6:WAITING, Maker_7:WAITING, pool-7-thread-1:TIMED_WAITING, pool-7-thread-2:TIMED_WAITING, pool-8-thread-1:TIMED_WAITING, pool-8-thread-2:TIMED_WAITING, pool-6-thread-1:TIMED_WAITING, pool-6-thread-2:TIMED_WAITING, pool-5-thread-1:TIMED_WAITING, pool-5-thread-2:TIMED_WAITING, pool-1-thread-1:TIMED_WAITING, pool-3-thread-1:TIMED_WAITING, pool-2-thread-1:TIMED_WAITING, pool-1-thread-2:TIMED_WAITING, pool-4-thread-1:TIMED_WAITING, pool-4-thread-2:TIMED_WAITING, pool-3-thread-2:TIMED_WAITING, pool-2-thread-2:RUNNABLE]
2016-09-12 21:31:45.082 :: [Maker_0:WAITING, Maker_1:WAITING, Maker_2:WAITING, Maker_3:WAITING, Maker_4:WAITING, Maker_5:WAITING, Maker_6:WAITING, Maker_7:WAITING, pool-7-thread-1:TIMED_WAITING, pool-7-thread-2:TIMED_WAITING, pool-8-thread-1:TIMED_WAITING, pool-8-thread-2:TIMED_WAITING, pool-6-thread-1:TIMED_WAITING, pool-6-thread-2:TIMED_WAITING, pool-5-thread-1:TIMED_WAITING, pool-5-thread-2:TIMED_WAITING, pool-1-thread-1:TIMED_WAITING, pool-3-thread-1:TIMED_WAITING, pool-2-thread-1:TIMED_WAITING, pool-1-thread-2:TIMED_WAITING, pool-4-thread-1:TIMED_WAITING, pool-4-thread-2:TIMED_WAITING, pool-3-thread-2:TIMED_WAITING, pool-2-thread-2:TIMED_WAITING]
Anda akan melihat bahwa sub-utas dan mengubah negara mereka dan menunggu.