java方法阻止并发访问

use*_*006 6 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到这样的输出

1307082622317
1307082622317
1307082622317
1307082622317
BUILD SUCCESSFUL (total time: 11 seconds)
Run Code Online (Sandbox Code Playgroud)

任何建议?

Boh*_*ian 10

使你的方法静态:

private static synchronized void sync();
Run Code Online (Sandbox Code Playgroud)

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

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


Jon*_*eet 7

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

  • 如果在每个实例上对单独的对象进行同步,则会阻止两个线程运行同一对象的代码.这实际上就是你现在所拥有的,但你隐含地同步this,我会阻止你这样做.(任何其他代码都可以在同一个对象上同步.)
  • 如果一个对象上同步所有的情况下知道(例如,通过一个静态变量),那么只会让一个线程运行的代码在所有.

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

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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

保持sync同步方法但使其保持静态也会起作用,但是你再次锁定一个公开可见的对象(MC.class),我通常不鼓励这样做.