我有一个使用多个线程写入单个变量的应用程序" theVar"下面。 99%的时间我拥有正确的数据,但有时会丢失一些数据。我一直试图解决这个问题差不多一个星期了,我真的迷路了。它只是突然发生,我丢失数据,这是一个非常严重的问题。我做错了什么?
class Singleton {
private volatile Singleton instance;
private volatile String theVar = null;
private final Object lock = new Object();
public void setVar(String newVar) {
synchronized (lock) {
theVar = newVar;
}
}
public String getVar() {
synchronized (lock) {
return theVar;
}
}
public void appendVar(String text) {
synchronized (lock) {
theVar += text;
}
}
protected Singleton() {
}
public static Singleton getInstance() {
Singleton instance = this.instance;
if (instance == null) {
synchronized (this) {
instance = this.instance;
if (instance == null) {
instance = this.instance = new Singleton();
}
}
}
return instance;
}
}
答案 0 :(得分:2)
尝试这样的事情:
public enum Singleton {
INSTANCE;
private volatile String theVar = null;
public synchronized void setVar(String newVar) {
theVar = newVar;
}
public String getVar() {
return theVar;
}
public synchronized void appendVar(String text) {
theVar += text;
}
}
答案 1 :(得分:2)
Buddy,为了创建Singleton我的建议是使用以下方法,它是100%线程安全且没有同步问题,因为它利用了Java的类加载机制。
就像这个类Provider
只会被加载一次(JVM永远不会加载一个类两次)当第一次调用第一次调用getInstance()
时将存在一个Singleton类的实例。
即使2个线程同时尝试调用getInstance()
方法,但JVM也不会加载Provider
两次,因为我们正在创建Singleton
类实例作为静态的一部分初始化,这意味着在类加载时,因此只存在一个实例。
在你的情况下,在同一时间可能有两个线程导致一些问题;试试这个,我希望你能得到100%的结果。如果没有,那么请提供您如何运行相同的代码。
public class Singleton {
private Singleton() {
}
private volatile String theVar = null;
public void setVar(String newVar) {
synchronized (this) {
theVar = newVar;
}
}
public String getVar() {
synchronized (this) {
return theVar;
}
}
public void appendVar(String text) {
synchronized (this) {
theVar += text;
}
}
private static class Provider {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Provider.INSTANCE;
}
}