实现了一个存储文本的单例对象,在两个线程里不停地存入读取
单例类
public class Singleton {
private static Singleton defaultInstance;
private String info="";
private Singleton(){};
public static Singleton getInstance(){
if(defaultInstance==null){
synchronized (Singleton.class) {
if(defaultInstance==null){
defaultInstance=new Singleton();
}
}
}
return defaultInstance;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
线程类
public class singleton_thread extends Thread{
private String name="";
private Singleton singleton = Singleton.getInstance();
public singleton_thread(String string) {
name=string;
}
public Singleton getSingleton() {
return singleton;
}
public void run() {
int i=1;
while(i<1000){
System.out.println(name+"第"+i+"次读取:"+singleton.getInfo());
i++;
singleton.setInfo(name+"的第"+i+"次注入值");
}
}
}
测试类
public class test {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
singleton_thread thread1= new singleton_thread("A");
singleton_thread thread2= new singleton_thread("B");
singleton.setInfo("确认单例:"+thread1.getSingleton().equals(thread2.getSingleton()));
thread1.start();
thread2.start();
}
}
输出如下:
A第1次读取:确认单例:true
B第1次读取:确认单例:true
A第2次读取:A的第2次注入值
B第2次读取:B的第2次注入值
A第3次读取:A的第3次注入值
B第3次读取:B的第3次注入值
A第4次读取:A的第4次注入值
B第4次读取:B的第4次注入值
...
问题来了,
按这个顺序
A第2次读取:A的第2次注入值
这个时候单例的值应该是
A的第3次注入值
所以下一行应该是
B第2次读取:A的第3次注入值
但实际上是
B第2次读取:B的第2次注入值
这是为什么??
然后,在thread的while中加入sleep(10)后
输出
A第1次读取:确认单例:true
B第1次读取:确认单例:true
A第2次读取:B的第2次注入值
B第2次读取:B的第2次注入值
A第3次读取:B的第3次注入值
B第3次读取:B的第3次注入值
A第4次读取:B的第4次注入值
B第4次读取:B的第4次注入值
这个时候能对上了,说明的确存在互相覆盖,只不过ab同时在存入。B晚一点而已
那么在不sleep的时候为什么线程之间完全不互相覆盖,反而有点像是A执行完了才执行B,只不过打印的时候乱掉了。如果不是的话,是不是意味着单例是无效的?
问这个问题是担心如果是没有sleep的场景(比如用户高频率的调用spring的controller)会不会发生意想不到的情况