首页 新闻 会员 周边 捐助

多线程使用中单例变量和static变量的区别

0
悬赏园豆:20 [已解决问题] 解决于 2019-07-05 11:40

今天看到一个多线程问题解决了以后想再优化一下,用static代替单例获取变量:

class Test3 {
    private static Test3 t;
    public volatile int temp = 128;

    public static synchronized Test3 getInstance(){
        if(t == null){
            t = new Test3();
        }
        return t;
    }

}

改为:

class Test3 {
    public static int temp = 128;
}

然后发现线程执行temp累加,
10次结果是对的
100次后找不到228,只能找到227,temp结果大致是正确的的
随着循环次数的增加重复的数字就越多,
这是为什么,
static修饰的类变量不是只有一个内存地址么,那和使用单例获取有什么区别(使用单例获取变量一切正常)

问题补充:

代码如下:

package ExecutorTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test1 {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        for (int i =0; i<1000; i++){
            service.execute(new Test2());
        }
        service.shutdown();
        while (!service.isTerminated()){
        }
    }
}

class Test2 implements Runnable{

    @Override
    public void run() {
        Test3 test3 ;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (test3= new Test3()){
            test3.temp = test3.temp +1;
            System.out.println(test3.temp);
        }
    }
}

class Test3 {
    public static volatile  int temp = 128;
}
小光的主页 小光 | 小虾三级 | 园豆:1766
提问于:2019-07-05 10:42

博问支持 markdown 代码高亮语法

dudu 5年前

@dudu: 好的,搜了一下会用了,之前都是自动让编辑器弄的。。。

小光 5年前
< >
分享
最佳答案
0

static修饰的类变量不是只有一个内存地址么,你没说错,但是你想一想 计算机是怎么做加法的。

  1. 先从地址拿到值放到寄存器
    2.寄存器里面加法算好
    3.在把变量的值修改(严格意义上不准确,但是基本可以这么理解)
    那么,假设temp=1, 然后2个线程同时执行1,2, 在先后执行3。那是不是本来temp应该是3的,结果确实2.

所以你测试的时候,会循环了100次,而temp累计的值可能不够100.

volatile 关键字就不解释了,直接baidu把。

收获园豆:10
czd890 | 专家六级 |园豆:14482 | 2019-07-05 11:28

嗯,突然想通了,我阻塞的是对象,现在不用单例获取变量值,相当于阻塞失效了,只用到了static共享变量,现在temp没有锁了

小光 | 园豆:1766 (小虾三级) | 2019-07-05 11:33
其他回答(1)
0

兄弟,你代码太乱了,都没心情看,这个编辑器是支持Markdown的,建议格式化一下代码。另外变量肯定是一个呀,要不就不需要考虑多线程安全了,如果每个线程都操作独自的变量,那还说个啥,所以和静态不静态没关系。

收获园豆:10
会长 | 园豆:12461 (专家六级) | 2019-07-05 11:17

之前都是让编辑器自动显示的,改好了,我好像知道了,我阻塞的是对象,现在不用单例获取变量值,相当于阻塞失效了,只用到了static共享变量,现在temp没有锁了

支持(0) 反对(0) 小光 | 园豆:1766 (小虾三级) | 2019-07-05 11:32

和静态有关系吧,这个结果的累加,是因为静态变量共享的关系,如果不用static值就不会累加,都是129

支持(0) 反对(0) 小光 | 园豆:1766 (小虾三级) | 2019-07-05 11:39

@小光: 哦,解决就好,刚才代码太乱,我都看,就是说了下自己对多个线程读写同一个变量的认识。

支持(0) 反对(0) 会长 | 园豆:12461 (专家六级) | 2019-07-05 11:43

@会长: 嗯,之前代码都是自动高亮显示的,现在要自己弄了,刚知道Markdown这个东西。。

支持(0) 反对(0) 小光 | 园豆:1766 (小虾三级) | 2019-07-05 11:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册