java - Mencari penjelasan sekeping kod sumber dalam ArrayBlockingQueue
阿神
阿神 2017-05-27 17:41:19
0
2
884

Mengapa kaedah take() menggunakan gelung sementara dan bukannya jika apabila menilai sama ada bilangan elemen dalam baris gilir adalah

我认为,如果notEmpty.await()方法既然苏醒返回了 ,那么此线程肯定拿到了lock。

Sebab untuk bangun juga adalah kerana kaedah put() memasukkan elemen baharu, dan benang lain tidak boleh mendapatkan kunci, jadi secara semula jadi mereka tidak boleh mengambil elemen Jadi pada masa ini, untuk benang yang mendapat kunci itu count pastinya bukan 0. Anda harus berasa bebas untuk melaksanakan dequeue() untuk mendapatkan elemen.
Saya tidak tahu apa yang penulis maksudkan dengan menggunakan sambil?

阿神
阿神

闭关修行中......

membalas semua(2)
漂亮男人

"Memandangkan kaedah notEmpty.await() bangun dan kembali, maka benang ini mesti telah mendapat kunci" Ayat ini betul.

Andaikan kod yang anda tulis ialah:

if (count == 0)
    notEmpty.await();

Satu perkara yang jelas ialah kita perlu memastikan bahawa syarat yang perlu dipenuhi sebelum return dequeue() ialah count != 0. Kami menganggap bahawa utas A telah memperoleh return dequeue() 之前需要满足的一个条件是 count != 0。我们假设 线程A 此时拿到了 lock,那么 线程A 的 notEmpty.await() 此时便会停止阻塞,准备向下执行 return dequeue()。但是假设在竞争激烈的条件下,线程A 拿到 lock 之后,准备执行下一条 JVM 指令的时候,线程B 此时抢占了 lock,然后继续向下执行 return dequeue(),刚好使得 count 变为了 0;而此时因为写的只是 if(count == 0),那么线程 A 在拿到 lock 之后,还是会继续向下执行 return dequeue(),从而导致了错误。

关于为什么wait()await()lock pada masa ini, maka notEmpty.await() utas A akan berhenti menyekat pada masa ini dan bersedia untuk melaksanakan menunggal gilir balik (). Tetapi dengan mengandaikan bahawa dalam keadaan persaingan yang sengit, selepas utas A mendapat kunci, apabila bersedia untuk melaksanakan arahan JVM seterusnya, utas B merampas kunci pada masa ini, dan kemudian terus melaksanakan return dequeue(), Ini hanya menjadikan kiraan menjadi 0; dan kerana apa yang ditulis pada masa ini hanya if(count == 0), maka thread A akan terus melaksanakan return dequeue(( ), menyebabkan ralat. Mengenai mengapa wait() dan wait() ialah kaedah yang menyekat apabila syarat tidak dipenuhi mesti

sebentar lagi gelung Untuk digunakan dalam, sila rujuk Artikel 69 (halaman 244) edisi kedua "#🎜🎜#Jawa Berkesan#🎜🎜#". #🎜🎜#
黄舟
public ArrayBlockingQueue(int capacity, boolean fair) {
    if (capacity <= 0)
        throw new IllegalArgumentException();
    this.items = new Object[capacity];
    lock = new ReentrantLock(fair);
    notEmpty = lock.newCondition();    //notEmpty 就是这个锁的条件
    notFull =  lock.newCondition();
}

Jadi apabila baris gilir semasa dalam kod anda kosong (kira == 0), panggilan notEmpty.await(),这段代码对锁是有影响的,实际上底层上已经释放了锁,只是这个方法保证了被唤醒时一定又能够拿回锁(当有元素放入队列会调用notEmpty.signal()进行唤醒),那为什么需要使用while呢?因为insert后lock.unlock,未必notEmpty.await() akan membangunkan anda serta-merta. Anda boleh memasukkan benang untuk menjalankan kaedah alih keluar sebelum

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan