我有數據的一個實例,在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