我有一个像这样的代码块:
if(supportsSomeStuff()){
.....
.....
}
else {
.....
.....
}
现在我希望在多次读取,单次写入锁定中使用此代码块。 在这种情况下,最好是锁定if语句,然后在if之后释放锁定 锁定else语句并在完成后释放它?
或者,我可以为这个if-else案例设置一个锁,并在完成后释放它吗?
如果我需要做出决定,我需要考虑哪些因素?
如果您需要更多信息,请与我们联系。
答案 0 :(得分:1)
您在考虑以下两种变体吗?
synchronized(lock) {
if(supportsSomeStuff()){
.....
}
else{
.....
}
}
VS
if(supportsSomeStuff()){
synchronized(lock) {
.....
}
}
else{
synchronized(lock) {
.....
}
}
它们之间唯一(巨大的)区别是if
语句中的条件在后一种情况下不同步。除此之外(如果supportsSomeStuff()
可以在多个线程中执行)它们是等效的,尽管前一种情况持有稍微更长时间的锁。
答案 1 :(得分:0)
如果在此方法中您正在更改状态,则锁定该
假设你正在改变StringBuilder然后锁定你的StringBuilder名为changingvalue而supportsSomeStuff是无状态的
if(supportsSomeStuff()){
//Considering that if will be executed when write needs to be done and else when read to be done
copyOnWriteStringBuilder = new StringBuilder(changingvalue.toString());//This will ensure that before every write you have taken a backup so concurrent read will see the last updated values
synchronized(changingvalue) {
//doSomething and then place the updated value in copyOnWriteStringBuilder too
}
}
else{
return copyOnWriteStringBuilder; // This piece for read no locking
}
答案 2 :(得分:0)
我会说:
lock(); try { ... } finally { unlock(); }
模型来帮助您做出决定。如果代码更干净,只需将整个if包装在该模型中,那就去吧。我认为除非我遗漏了某些内容,否则以下内容最为干净。
lock.lock();
try {
if(supportsSomeStuff()){
...
} else {
...
}
} finally {
lock.unlock();
}
如果您担心if
测试被锁定且不需要,那么请不要这样做。 应该担心的唯一一次是,如果测试本身调用的其他方法可能是您不需要并且不想被锁定的性能损失。
答案 3 :(得分:0)
你并没有提供足够的信息来提供更多的答案。
但总的来说,你应该尝试找到以下几者之间的最佳折衷方案:
这些竞争因素之间的最佳妥协取决于您的情况。
顺便提一下,很多人都建议内置'同步'锁,但是既然你提到你只需要一个写线程,那么根据你的情况你可以通过ReentrantReadWriteLock获得更好的吞吐量。
答案 4 :(得分:-1)
读取不是排他性的,但写入是;这意味着可以有多个同时读取,但写入只能是一个,当写入发生时,不允许读取。
这取决于你在哪里做。将写入的块限制为最小值。