如果我想防止两个线程同时操作synchronized
,我需要在哪里放置关键字tab
?
Mainclass
拥有变量tab
,方法f1,f2,f3
正在操纵tab
。 f2,f2
由循环中的main方法调用,并且f3
由主线程中事件发生后x
毫秒内的线程调用。
主要方法:
main() {
Mainclass mainclass = new Mainclass(); // class containing variable tab
while (condition) {
mainclass.f1(); // manipulating tab
mainclass.f2(); // manipulating tab
if (eventOccured) {
mainclass.startThread(x);
// thread calls f3() after x milliseconds whitch is manipulating tab
}
}
}
IMainclass:
public class Mainclass {
public void f1(){...} // manipulating tab
public void f2(){...} // manipulating tab
public void f3(){...} // manipulating tab
public final TabObject[][] tab;
}
我可以同步tab
,还是必须同步f1,f2,f3
,我应该使用像synchronized (tab) {...}
这样的同步块,还是同步整个mehtods?
答案 0 :(得分:2)
最简单的方法是同步f1
,f2
和f3
。但是,这意味着在任何时候,这些方法中至多可以运行其中一种方法。如果这些方法执行与tab
无关的重度计算,则会出现一些性能问题。
例如,假设以下内容:
public void f1() {
/*
Do some I/O, e.g. read in/write very large files (typically very slow)
*/
synchronized(tab) {
// Than manipulate "tab"
}
}
在这种情况下,最好在选项卡操作周围使用同步块,而不是同步整个方法。这样做,f1
,f2
和f3
可以同时运行以执行一些缓慢的I / O操作,并且仅在操作tab
时同步,可能会导致更好的操作性能
答案 1 :(得分:2)
synchronized void A(){
...
}
相当于
void A(){
synchronized(this) {
...
}
}
但使用this
作为锁is not a good idea。
如果不知道方法的细节,你可以像你说的那样使用synchronized (tab) {...}
块,但我只是用它来包装实际读/写tab
的行。 var而不是整个方法。
如果你想让事情更清洁,你甚至可以添加
private final Object lock = new Object();
并使用synchronized (lock) {...}
而不是同步到tab
(public
,这意味着另一个类可能会与其同步导致死锁)。
答案 2 :(得分:1)
您可以定义一个监视器对象,如private Object monitor = new Object();
,并调用同步块内的代码操作选项卡,如
您可以将此同步块放在方法f1,f2,f3中,如:
public void f1()
{
synchronized(monitor)
{
//code to manipulate tab
}
}