并发执行静态和非静态同步方法的问题?

div*_*ivz 4 java

在以下示例中

  1. 如果不同的线程同时尝试访问静态和非静态同步方法会发生什么,并反过来尝试使用这两种方法更改静态数据?
  2. 使用run()方法的do-while循环为每个非静态同步方法调用创建BadDesign类的新对象是否有任何问题?
  3. 这个Java代码是否正确同步?

以下是说明我的问题的示例代码:

BadDesign.java

public final class BadDesign{

    private static int sensitiveData;

    public synchronized static void changeDataViaStaticMethod(int a){
        //... updating the sensitiveData
        sensitiveData = a;
    }


    public synchronized void changeDataViaNonStaticMethod(int b){
        //... updating the sensitiveData
        sensitiveData = b;
    }


    public static void showSensitiveDataStatic(){
        System.out.println("Static: " + Thread.currentThread().getName()+ " - " + sensitiveData);
    }


    public void showSensitiveData(){
        System.out.println(Thread.currentThread().getName() + " - " + sensitiveData);
    }


    public static void main(String[] args){

        new Thread(new TestThread11()).start();
        new Thread(new TestThread11()).start();
    }
}
Run Code Online (Sandbox Code Playgroud)

和TestThread11.java

class TestThread11 implements Runnable{
    public void run(){
        int i = 0;

        do{
            BadDesign.changeDataViaStaticMethod(5);
            BadDesign.showSensitiveDataStatic();

            //... new object for every iteration

            //... so synchronization of non-static method

            //... doesn't really do anything significant here

            BadDesign bd = new BadDesign();
            bd.changeDataViaNonStaticMethod(10);
            bd.showSensitiveData();

        }while (i++ < 100);
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

非静态版本将允许两个不同的线程通过不同的对象进入,获取不同的锁并仍然访问相同的共享数据.从根本上说,这不是线程安全的,并且基本上使锁无用.您希望一个锁可以覆盖任何共享数据.

如果你真的想要,你仍然可以使用非静态方法(例如,如果结果应该部分地由实例数据确定),但你应该通过共享锁访问共享数据,例如

private static final Object staticLock = new Object();

...

synchronized (staticLock)
{
    // Read or write static data
}
Run Code Online (Sandbox Code Playgroud)