concurrent API提供了一个名为Lock的类,它将序列化控件以访问关键资源。它给出了park()和unpark()等方法。
如果我们可以使用synchronized关键字并使用wait()和notify() notifyAll()方法,我们也可以做类似的事情。
我想知道哪一个在实践中更好,为什么?
concurrent API提供了一个名为Lock的类,它将序列化控件以访问关键资源。它给出了park()和unpark()等方法。
如果我们可以使用synchronized关键字并使用wait()和notify() notifyAll()方法,我们也可以做类似的事情。
我想知道哪一个在实践中更好,为什么?
当前回答
你可以实现java.util.concurrent中的实用程序使用低级原语(如synchronized、volatile或wait / notify)所做的所有事情
然而,并发性是棘手的,大多数人至少在某些方面犯了错误,导致他们的代码要么不正确,要么效率低下(或两者兼而有之)。
并发API提供了更高级的方法,使用起来更容易(因此也更安全)。简而言之,你不应该再直接使用synchronized、volatile、wait、notify了。
Lock类本身在这个工具箱的底层,你甚至不需要直接使用它(你可以使用queue和Semaphore等等,大多数时候)。
其他回答
你可以实现java.util.concurrent中的实用程序使用低级原语(如synchronized、volatile或wait / notify)所做的所有事情
然而,并发性是棘手的,大多数人至少在某些方面犯了错误,导致他们的代码要么不正确,要么效率低下(或两者兼而有之)。
并发API提供了更高级的方法,使用起来更容易(因此也更安全)。简而言之,你不应该再直接使用synchronized、volatile、wait、notify了。
Lock类本身在这个工具箱的底层,你甚至不需要直接使用它(你可以使用queue和Semaphore等等,大多数时候)。
锁和同步的主要区别:
使用锁,您可以以任何顺序释放和获取锁。 使用synchronized,您只能按照获取锁的顺序释放锁。
锁和同步块都有相同的目的,但这取决于使用情况。考虑以下部分
void randomFunction(){
.
.
.
synchronize(this){
//do some functionality
}
.
.
.
synchronize(this)
{
// do some functionality
}
} // end of randomFunction
在上述情况下,如果一个线程进入同步块,另一个块也被锁定。如果在同一个对象上有多个这样的同步块,则所有的同步块都被锁定。在这种情况下,可以使用java.util.concurrent.Lock来防止不必要的块锁定
主要的区别是公平性,换句话说,请求是FIFO处理还是可以有驳船?方法级同步确保公平或FIFO分配锁。使用
synchronized(foo) {
}
or
lock.acquire(); .....lock.release();
不能保证公平。
如果您对锁有很多争用,那么您很容易遇到barging,即新请求获得锁而旧请求卡住。我曾经见过这样的情况:为了一个锁,200个线程在短时间内到达,而第二个到达的线程最后被处理。这对于某些应用程序是可行的,但对于其他应用程序则是致命的。
请参阅Brian Goetz的《Java并发实践》一书中的13.3节,以获得关于此主题的完整讨论。
为什么要使用synchronized或java.util.concurrent.Lock有4个主要因素。
注意:同步锁定就是我所说的内在锁定。
When Java 5 came out with ReentrantLocks, they proved to have quite a noticeble throughput difference then intrinsic locking. If youre looking for faster locking mechanism and are running 1.5 consider j.u.c.ReentrantLock. Java 6's intrinsic locking is now comparable. j.u.c.Lock has different mechanisms for locking. Lock interruptable - attempt to lock until the locking thread is interrupted; timed lock - attempt to lock for a certain amount of time and give up if you do not succeed; tryLock - attempt to lock, if some other thread is holding the lock give up. This all is included aside from the simple lock. Intrinsic locking only offers simple locking Style. If both 1 and 2 do not fall into categories of what you are concerned with most people, including myself, would find the intrinsic locking semenatics easier to read and less verbose then j.u.c.Lock locking. Multiple Conditions. An object you lock on can only be notified and waited for a single case. Lock's newCondition method allows for a single Lock to have mutliple reasons to await or signal. I have yet to actually need this functionality in practice, but is a nice feature for those who need it.