Java同步多线程示例
如果要防止两个线程同时操作Java同步多线程示例,java,multithreading,Java,Multithreading,如果要防止两个线程同时操作选项卡,我需要将关键字synchronized放在哪里 Mainclass拥有变量tab它的方法f1、f2、f3正在操作tabf2、f2由循环中的主方法调用,而f3由线程在主方法中发生事件后的x毫秒内调用 主要方法: main() { Mainclass mainclass = new Mainclass(); // class containing variable tab while (condition) { mainclass.f
选项卡
,我需要将关键字synchronized
放在哪里
Mainclass
拥有变量tab
它的方法f1、f2、f3
正在操作tab
f2、f2
由循环中的主方法调用,而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){…}
这样的同步块还是同步整个方法?您可以定义像private object monitor=new object()这样的监视对象
并在同步块内调用代码操纵选项卡,如
您可以将此同步块放置在方法f1、f2、f3中,如下所示:
public void f1()
{
synchronized(monitor)
{
//code to manipulate tab
}
}
您可以定义一个监视对象,如
private object monitor=new object()
并在同步块内调用代码操纵选项卡,如
您可以将此同步块放置在方法f1、f2、f3中,如下所示:
public void f1()
{
synchronized(monitor)
{
//code to manipulate tab
}
}
最简单的方法是同步
f1
、f2
和f3
。然而,这意味着在任何时候,这些方法中最多有一个可以运行。如果这些方法正在执行一些与选项卡
无关的繁重计算,则可能会出现一些性能问题
例如,假设以下情况:
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操作,并且仅在操作选项卡时进行同步,可能会产生更好的性能。最简单的方法是同步f1
、f2
和f3
。然而,这意味着在任何时候,这些方法中最多有一个可以运行。如果这些方法正在执行一些与选项卡
无关的繁重计算,则可能会出现一些性能问题
synchronized void A(){
...
}
例如,假设以下情况:
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操作,并且仅在操作选项卡时同步,可能会产生更好的性能
synchronized void A(){
...
}
相当于
void A(){
synchronized(this) {
...
}
}
但是使用这个
作为锁
在不知道这些方法的细节的情况下,您可以像您所说的那样使用synchronized(tab){…}
块,但是我只会使用它来包装实际读取/写入tab
var的行,而不是将它用于整个方法
如果你想让东西更干净,你甚至可以添加
private final Object lock = new Object();
并使用synchronized(lock){…}
代替同步到tab
(即public
,这意味着另一个类可能会同步到它,从而导致死锁)
相当于
void A(){
synchronized(this) {
...
}
}
但是使用这个
作为锁
在不知道这些方法的细节的情况下,您可以像您所说的那样使用synchronized(tab){…}
块,但是我只会使用它来包装实际读取/写入tab
var的行,而不是将它用于整个方法
如果你想让东西更干净,你甚至可以添加
private final Object lock = new Object();
并使用synchronized(lock){…}
代替同步到tab
(这是public
,意味着另一个类可能会同步到它,从而导致死锁)。@svasa找到了这个主题,很好地解释了为什么不应该这样做@svasa注意到,在这种情况下,tab
被声明为final
,因此之后不能将其设置为null。我知道为什么不应该这样做,但如果我使用一些getter方法重置我的“tab”,比如tab=getValues();这很可能来自第三方jar,出于某种原因,getValues()返回null。在此之前,若tab被声明为final,那个么它如何被“操纵”?知道它可能返回null
,您应该在分配它之前明确地检查它。Ps:如果你做了tab=…
它不是一个getter,而是tab.Ok的setter。我的意思是使用getter设置tab值。@svasa找到了这个主题,很好地解释了为什么不应该这样做@svasa注意到,在这种情况下,tab
被声明为final
,因此之后不能将其设置为null。我知道为什么不应该这样做,但如果我使用一些getter方法重置我的“tab”,比如tab=getValues();这很可能来自第三方jar,出于某种原因,getValues()返回null。在此之前,若tab被声明为final,那个么它如何被“操纵”?知道它可能返回null
,您应该在分配它之前明确地检查它。Ps:如果你做了tab=…
它不是一个getter,而是tab.Ok的setter。我的意思是使用getter设置tab值。对象lock
将只是标记一个关键操作正在运行,或者在某种意义上。基本上,每个Java对象都有一个用于同步的隐式锁(这就是为什么synchronized
方法类似于synchronized(this)
块),但是使用private对象而不是this
可以让代码更“安全”。我不确定这是否是你问的问题,因此如果我误解了你的问题,请让我知道:)对象lock
将只是标记关键操作正在运行,或者在某种意义上。基本上,每个Java对象都有一个用于同步的隐式锁(这就是为什么synchronized