java方法防止并发访问

java方法防止并发访问,java,multithreading,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();

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

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)
我得到这样的输出

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)

有什么建议吗?

您有四个单独的MC对象。通常在这些(
sync
)上运行实例方法,它们不应该相互干扰。您可以使用<代码>同步块,以确保每次只运行一个,但您需要考虑同步:

  • 如果对每个实例在一个单独的对象上进行同步,这将阻止两个线程为同一个对象运行代码。这实际上就是您现在所拥有的,但是您正在隐式地同步
    这个
    ,我不鼓励您这样做。(任何其他代码都可以在同一对象上同步。)
  • 如果在所有实例都知道的对象上进行同步(例如,通过静态变量),那么只允许一个线程运行代码
听起来你想要后一种方法,但对我来说,这听起来不是一个很好的设计。如果您真的想以这种方式实现,您可以使用:

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
),我通常不鼓励这种做法。

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

使方法静态:

private static synchronized void sync();
编码的方法在实例上是同步的,但每个线程都有自己的实例,因此没有同步


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

使用静态锁来同步方法。锁类位于java.concurent包中

对于所需的功能,可以将sync函数设置为静态。我不谈论设计的好处。就按你喜欢的方式做吧

private static synchronized void sync()

Hi-u正在创建ur类MC的新实例,synchronized方法保证一个实例的单次访问,如果它不是静态方法的话

我建议您使用一个私有静态变量,比如Integer lock,然后对其进行同步:

私有void sync() {

已同步(锁定) {

}


}

期望的输出是什么?你想要达到什么?呵欠-看看我的答案:只需制定方法static@Bohemian:正如我在回答的最后特别指出的,这会起作用,但这意味着锁定一个公共可见的对象。这不是一个好主意,IMO-我喜欢能够对我的代码进行推理,因为我知道没有其他东西可以锁定相同的对象。@Jon_Skeet:这很公平,但坦率地说,整个类“设计得不太好”,仅用于演示目的,所以这个快速修复程序回答了他的“wtf正在进行”问题。@Bohemian:如果你想,你可以选择快速修复,但我宁愿质疑设计,同时提及最佳实践。我认为OP会通过这种方式学到更多,即使你只是打哈欠……这就足够了:同步(MC.class){