PV操作是Edsger Dijkstra提出的一种经典的解决同步不同执行线程的问题的方法,这种方法是基于一种叫信号量的特殊变量来实现的。
简单理解为就是通过共享变量+信号量实现的一种同步机制,其应用与生产者消费者模型,读写问题等领域。
在Java中有基于AQS实现的Semaphore信号量类。
wiki对于其名字来源的解释
https://en.wikipedia.org/wiki/Semaphore_(programming)#Operation_names
可以做出以下对比:
P(down/signal/release/pend/try to reduce)
V (up/wait/acquire/post/try to increase)
通俗的讲,P操作对应加锁,V操作对应解锁。加锁对应的是P将信号量减1,并阻塞其他线程,解锁对应的是V将信号量加1,并唤醒某一个线程。
在Java的ReentrantLock类中,lock方法对应acquire(1)方法,unlock对应release(1),是否与上面定义不一致?不是的,在p操作加锁中,对应release,其实是对于一个事物的两种表达而已。对于p操作,进入共享区的线程可以理解为release信号量,但是给别的线程加锁,lock。
下面画图理解:
三个线程同时访问共享区,t1先进入,执行p操作,将信号量s从1置为0,此时t2,t3程在进入共享区的话,发现s=0,p操作会挂起t2,t3。当t1离开共享区的时候,执行v操作,将信号量s从0置为1,并且唤醒t2或者t3,然后t2又将信号量s从1置为0,重复上面动作,从而返回循环该pv操作。
可以看出,p操作阻塞其他线程,也就是加锁。v操作唤醒其他线程。也就是解锁。
转载于:https://blog.51cto.com/thinklili/2123507