第二个读线程经历同样的过程。
对于阻塞队列,只有读线程需要在队列中没有数据时等待。
In a blocking queue, only the reader thread needs to wait when there is no data in the queue.
因此,最后两个读线程都等待条件变量,互斥锁没有被锁住。
Therefore, at the end of it all, you now have two reader threads, both waiting on the condition variable, and the mutex is unlocked.
因此,在唤醒读线程之后,要确认列表非空,然后再继续处理。
Hence, after waking up the reader thread, verify that the list is not empty, and then proceed.
当队列是空的时候,读线程现在并不抛出异常,而是在条件变量上阻塞自身。
Instead of throwing an exception when the queue is empty, the reader thread now blocks itself on the condition variable.
如果到超时时间段结束时还没有被唤醒,读线程需要唤醒自身并释放互斥锁。
If not awake otherwise, at the end of the timeout, the reader needs to wake itself up and release the mutex.
目前,如果读线程试图从没有数据的队列读取数据,仅仅会抛出异常并继续执行。
So far, if a reader thread wanted to read data from a queue that had no data, you just threw an exception and moved on.
接下来,读线程需要确保(这是第二个检查)它等待条件变量的时间不超过指定的超时时间。
Next, the reader thread needs to ensure (and this is the second check you perform) that it does not wait on the condition variable any more than the specified timeout period.
这么做会唤醒所有等待条件变量_ cond的读线程;读线程现在隐式地争夺互斥锁。
Doing so awakens all the reader threads that were waiting on the condition variable _cond; the reader threads now implicitly compete for the mutex lock as and when it is released.
但是,这种做法不总是我们想要的,读线程很可能希望等待(即阻塞自身),直到有数据可用时为止。
This may not always be the desired approach, however, and it is likely that the reader thread might want to wait or block itself until the time data becomes available.
如果在超时之前读线程被唤醒,pthread_cond _ timedwait的返回值是0。
If the reader thread is awakened before the timeout, the return value from pthread_cond_timedwait will be 0.
第一个读线程锁住互斥锁,发现队列是空的,然后在 _cond 上阻塞自身,这会隐式地释放互斥锁。
The first reader thread locked the mutex, realized that the queue is empty, and blocked itself on _cond, which implicitly released the mutex.
操作系统调度程序决定哪个线程获得对互斥锁的控制权—通常,等待时间最长的读线程先读取数据。
The operating system scheduler determines which thread gets control of the mutex next-typically, the reader thread that has waited the longest gets to read the data first.
如果队列满了,写线程等待_ wcond条件变量;读线程在从队列中取出数据之后需要通知所有线程。
If the queue is full, the writer thread waits on the _wcond condition variable; the reader thread will need a notification to all threads after consuming data from the queue.
显然,如果您使用的是原版的读/写锁,那么按照标准自旋锁的用法使用这个自旋锁,而不区分读线程和写线程。
Obviously, if your use of the lock is reader/writer in nature, this spinlock should be used over the standard spinlock, which doesn't differentiate between readers and writers.
这个函数与pthread_cond_wait相似,但是第三个参数是绝对时间值,到达这个时间时读线程自愿放弃等待。
This function is similar to pthread_cond_wait, except that the third argument is the absolute time value until which the reader thread is willing to wait before it gives up.
尽管使用pthread_cond_signal不会损害阻塞队列的功能,但是这可能会导致某些读线程的等待时间过长。
Although the functionality of the blocking queue is not compromised with this choice, use of pthread_cond_signal could potentially lead to unacceptable wait times for some reader threads.
一个写线程释放一个锁之后,另一个读线程随后获取了同一个锁。本质上,线程释放锁时会将强制刷新工作内存中的脏数据到主内存中,获取一个锁将强制线程装载(或重新装载)字段的值。
In essence, releasing a lock forces a flush of all writes from working memory employed by the thread, and acquiring a lock forces a (re) load of the values of accessible fields.
唯一的主要差别,如上所述,是这些阻塞读和写可以被其它线程中断。
The one major difference, mentioned above, is that these blocking reads and writes can be interrupted by other threads.
因为映射表的典型的读存取操作会改变顺序,如果多个线程可以从映射表读取,就应该同步存取操作。
Because the typical read-access of a map changes the order, if multiple threads could be reading from the map, you should synchronize access.
释放J VM结构的操作让gc线程以一种安全的形式处理这些结构;对部分更新的结构进行读和写操作可能导致不可预测的行为和冲突。
The act of releasing JVM structures lets the GC thread process these structures in a safe fashion; reading and writing to partially updated structures can cause unexpected behavior and crashes.
在阻塞模式中,线程将在读或写时阻塞,一直到读或写操作彻底完成。
In blocking mode, a thread will block on a read or a write until the operation is completely finished.
理想情况下,多个线程不能同时访问同一块数据,脏读将不复存在,死锁则会被自动监测和处理。
Ideally no two threads can try to modify the same piece of data at the same time, dirty reads are not possible, and deadlocks are automatically detected and handled.
没有同步时,如果一个线程读取另外一个线程正在写的变量,读的线程将看到过时的数据。
In the absence of synchronization, if one thread writes to a variable and another thread reads that same variable, the reading thread could see stale, or out-of-date, data.
如果一个线程想要从一个共享资源中修改或者读一个值,它必须先获取锁。
If a thread wishes to modify or read a value from a Shared resource, the thread must first gain the lock.
从一开始读一个线程,从另一个读取结束的想法会使事情变慢,因为寻找时间会杀了你。
But your idea of having one thread reading from the beginning and another reading from the end will make things slower because seek time is going to kill you.
如果有一个线程处于可升级读模式,并且没有任何线程等待进入写模式,那么任意数量的线程可以进入读模式,即使有线程在等待进入可升级读模式。
If a thread is in upgradeable mode, and there are no threads waiting to enter write mode, any number of other threads can enter read mode, even if there are threads waiting to enter upgradeable mode.
如果有一个线程处于可升级读模式,并且没有任何线程等待进入写模式,那么任意数量的线程可以进入读模式,即使有线程在等待进入可升级读模式。
If a thread is in upgradeable mode, and there are no threads waiting to enter write mode, any number of other threads can enter read mode, even if there are threads waiting to enter upgradeable mode.
应用推荐