我有数据的一个实例,在2线程之间共享我的类服务器:共享变量没有被修改
public class Server{
public static void main(String[] args){
Data data = new Data();
Thread t1=new Thread(new ClientService(data));
Thread t2=new Thread(new PromoService(data));
t1.start();
t2.start();
}
这里是我的课的有关部分:
public class ClientService implements Runnable{
public Data data;
public ClientService(Data data){
this.data = data;
}
public void run(){
this.data.newClient(t[1],Integer.parseInt(t[2]),Integer.parseInt(pass),ia);
}
在这里,让我们假设t是一个String数组,它是一个InetAdress并传递一个字符串(我已经移除了创建这些变量以使其更简单的代码部分)。
public class Data implements Serializable{
public ArrayList<ClientData> listClient;
public Data(){
this.listClient = new ArrayList<ClientData>();
}
public synchronized boolean newClient(String id,int port,int pass,InetAddress ia){
for(int i = 0 ; i < listClient.size(); i ++){
if(listClient.get(i).id.equals(id)){
return false;
}
}
ClientData ncl = new ClientData(port,ia,id,pass);
this.listClient.add(ncl);
return true;
}
在newClient()之前,listClient不包含任何内容(size = 0)。打电话后,我尝试打印listClient和大小已成为1,但包含的元素为空。我不明白:阻碍新的ClientData对象被添加到这个共享变量的东西? 当我尝试时,我确保此线程是唯一一个在此时访问或修改实例。
这只是一个想法,但试着将'listClient'声明为'final'或'volatile'。这可能是编译器做了一些有趣的事情,但我怀疑它同步应该确保自己的良好行为。此外,之后访问'listClient'的线程(以检查其中的内容)也需要在'data'上同步。 'synchronized(data){System.out.println(data.listClient); }' – Radiodef
我刚刚添加了这一行,它的工作原理非常感谢!但是我不明白为什么它会改变任何东西,如果我确定没有其他人在此刻正在调试它 – StuYYY
null的旧值仍然可以保存在寄存器中,而不是从RAM加载。为了减少遇到像这样的意外问题的风险,我会尽量不要手动执行任何同步,而是使用'java.util.concurrent.atomic.AtomicReference'的实例来保存我的共享变量。 – SpiderPig