java方法阻止并发访问

时间:2011-06-03 06:45:25

标签: java multithreading

如何防止并发访问。我有这样的代码

public class MC implements Runnable {

    public void run() {
        sync();
    }

    public static void main(String p[]){
        MC mc = new MC();
        MC mc2 = new MC();
        MC mc3 = new MC();
        MC mc4 = new MC();
        Thread t = new Thread(mc);
            t.start();
            Thread t2 = new Thread(mc2);
            t2.start();
            Thread t3 = new Thread(mc3);
            t3.start();
            Thread t4 = new Thread(mc4);
            t4.start();
    }

    private synchronized void sync(){
        try {
            System.out.println(System.currentTimeMillis());
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}

我正在获得这样的输出

1307082622317
1307082622317
1307082622317
1307082622317
BUILD SUCCESSFUL (total time: 11 seconds)

任何建议?

6 个答案:

答案 0 :(得分:9)

让您的方法保持静态:

private static synchronized void sync();

编码的方法在实例上同步,但每个线程都有自己的实例,因此没有同步。

静态方法在Class对象上同步,每个类只有一个,因此所有实例都将在静态方法上同步。

答案 1 :(得分:7)

你有四个独立的MC对象。通常在那些(sync)上运行实例方法,它们不应相互干扰。您可以使用synchronized块来确保一次只运行一个,但您需要考虑要同步的内容:

  • 如果在每个实例上对单独的对象进行同步,则会阻止两个线程运行同一对象的代码。这实际上就是你现在所拥有的,但你隐含地在this上进行同步,我不鼓励你这样做。 (任何其他代码都可以在同一个对象上同步。)
  • 如果您同步一个 all 实例知道的对象(例如通过静态变量),那么只允许一个线程运行代码 。< / LI>

听起来你想要后一种方法,但对我来说听起来并不是很棒。如果你真的想以这种方式实现它,你可以使用:

public class MC implements Runnable {

    private static readonly Object lock = new Object();

    ...

    private void sync() {
        synchronized (lock) {
            try {
                System.out.println(System.currentTimeMillis());
                Thread.sleep(10000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}

sync保持为同步方法但将其设置为静态可以正常工作,但是你又会锁定一个公开可见的对象(MC.class)阻碍。

答案 2 :(得分:4)

对于所需的功能,您可以使同步功能保持静态。我不谈论设计的优点。它就是按照你喜欢的方式做到的!

private static synchronized void sync()

答案 3 :(得分:0)

您正在实例化四个对象,而sychronized位于不同的监视器上。要使sync为静态,以便实际的类将成为监视器,或者在实例化时,将相同的监视器对象传递给所有四个,然后在其上同步

答案 4 :(得分:0)

使用静态锁同步您的方法。锁类在java.concurrent包中

答案 5 :(得分:0)

您正在创建ur类MC的新实例,如果一个实例不是静态方法,则synchronized方法可以保证单个访问。

我建议你有一个私有静态变量说整数锁,然后同步它:

private void sync() {

同步(锁定) {

    try {
        System.out.println(System.currentTimeMillis());
        Thread.sleep(10000);
    } catch (InterruptedException ex){
        ex.printStackTrace();
    }

}

}