今天看到一个多线程问题解决了以后想再优化一下,用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;
}
static修饰的类变量不是只有一个内存地址么,你没说错,但是你想一想 计算机是怎么做加法的。
所以你测试的时候,会循环了100次,而temp累计的值可能不够100.
volatile 关键字就不解释了,直接baidu把。
嗯,突然想通了,我阻塞的是对象,现在不用单例获取变量值,相当于阻塞失效了,只用到了static共享变量,现在temp没有锁了
兄弟,你代码太乱了,都没心情看,这个编辑器是支持Markdown的,建议格式化一下代码。另外变量肯定是一个呀,要不就不需要考虑多线程安全了,如果每个线程都操作独自的变量,那还说个啥,所以和静态不静态没关系。
之前都是让编辑器自动显示的,改好了,我好像知道了,我阻塞的是对象,现在不用单例获取变量值,相当于阻塞失效了,只用到了static共享变量,现在temp没有锁了
和静态有关系吧,这个结果的累加,是因为静态变量共享的关系,如果不用static值就不会累加,都是129
@小光: 哦,解决就好,刚才代码太乱,我都看,就是说了下自己对多个线程读写同一个变量的认识。
@会长: 嗯,之前代码都是自动高亮显示的,现在要自己弄了,刚知道Markdown这个东西。。
博问支持 markdown 代码高亮语法
– dudu 5年前@dudu: 好的,搜了一下会用了,之前都是自动让编辑器弄的。。。
– 小光 5年前