Java 如何证明使用静态变量是一个巨大的错误?

Java 如何证明使用静态变量是一个巨大的错误?,java,multithreading,Java,Multithreading,一般来说,java开发人员都知道我们必须使用“synchronized”来逐个控制方法的执行,但是我看到下面的代码选择静态变量来控制,我无法模拟条件来证明方法是错误的,我如何修改代码以输出值超过1000 public class ThreadJunk implements Runnable{ private Info info; public ThreadJunk(Info info) { this.info = info; } public st

一般来说,java开发人员都知道我们必须使用“synchronized”来逐个控制方法的执行,但是我看到下面的代码选择静态变量来控制,我无法模拟条件来证明方法是错误的,我如何修改代码以输出值超过1000

public class ThreadJunk implements Runnable{
    private Info info;
    public ThreadJunk(Info info) {
        this.info = info;
    }
    public static void main(String args[]) throws Exception {

        for(int j=0;j<100;j++) {
            Info ii = new Info();
            for(int i=0;i<1000;i++) {
                Thread t = new Thread(new ThreadJunk(ii));
                t.start();
            }
            System.out.println(ii.getValue());
        }
    }
    @Override
    public void run() {
        info.addValue();
    }
}

class Info {
    public static boolean IS_LOCKED = false;
    private int value = 0;
    public void addValue() {
        if(IS_LOCKED)
            return;
        IS_LOCKED = true;
        value++;
        IS_LOCKED = false;
    }
    public int getValue() {
        return value;
    }
}
公共类ThreadJunk实现可运行{
私人信息;
公共线程垃圾(信息){
this.info=info;
}
公共静态void main(字符串args[])引发异常{

对于(int j=0;j请查看代码的这一部分:

Info ii = new Info();
for (int i = 0; i < 1000; i++) {
    Thread t = new Thread(new ThreadJunk(ii));
    t.start();
}
Info ii=新信息();
对于(int i=0;i<1000;i++){
螺纹t=新螺纹(新螺纹(ii));
t、 start();
}

对于您正在创建的每个
Info
对象,其线程数不超过
1000
个。您不应期望
value
字段的增量超过
1000
次。

Info
对象的成员变量为
value
。根据线程创建日志,999个线程中共享一个Info对象集成电路

 for(int j=0;j<100;j++) {
            Info ii = new Info();
            for(int i=0;i<1000;i++) {
                Thread t = new Thread(new ThreadJunk(ii));
                t.start();
            }
            System.out.println(ii.getValue());
        }

我会使用在两个以上线程中访问的静态
SimpleDataFormat
实例。其中一个线程应该写入System.out,并始终使用相同的输入日期触发(为此,我建议每年的2月28日),而其他线程不断使用同一实例来转换随机日期。这是一个非常精彩的演示,说明了为什么不在多线程环境中随意使用非线程安全对象…@ppeterka为什么要将其作为注释发布?这是一个很好的答案。@DuncanJones目前我没有足够的资源将其转化为完整的示例-成熟的答案…但我会在找到一个时隙时这样做-没有其他人这样做…确切地说。此外,还有一个竞争条件:使用
ii.getValue()
检索值,但不确保所有线程都已完成。这就是为什么(至少在我的环境上)打印的数字有时低于1000,这似乎是正在发生的事情。如果(被锁定)返回,此代码表示两个线程可能同时执行以下代码
System.out.println(ii.getValue())