Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java同步多线程示例_Java_Multithreading - Fatal编程技术网

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