Java同步多线程示例

时间:2016-02-14 14:54:26

标签: java multithreading

如果我想防止两个线程同时操作synchronized,我需要在哪里放置关键字tab

Mainclass拥有变量tab,方法f1,f2,f3正在操纵tabf2,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?

3 个答案:

答案 0 :(得分:2)

最简单的方法是同步f1f2f3。但是,这意味着在任何时候,这些方法中至多可以运行其中一种方法。如果这些方法执行与tab无关的重度计算,则会出现一些性能问题。

例如,假设以下内容:

public void f1() {

    /*
       Do some I/O, e.g. read in/write very large files (typically very slow)
    */

    synchronized(tab) {
        // Than manipulate "tab"
    }
}

在这种情况下,最好在选项卡操作周围使用同步块,而不是同步整个方法。这样做,f1f2f3可以同时运行以执行一些缓慢的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) {...}而不是同步到tabpublic,这意味着另一个类可能会与其同步导致死锁)。

答案 2 :(得分:1)

您可以定义一个监视器对象,如private Object monitor = new Object();,并调用同步块内的代码操作选项卡,如

您可以将此同步块放在方法f1,f2,f3中,如:

public void f1()
{

   synchronized(monitor)
   { 
     //code to manipulate tab
   }
}