线程之间的共享变量未修改

时间:2017-04-15 02:07:51

标签: java multithreading

我在我的类Server中有一个Data实例,在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,但是包含的元素为null。我不明白:阻碍将新的ClientData对象添加到此共享变量的东西是什么? 当我尝试时,我确保此线程是唯一一个在此时访问或修改实例的线程。

1 个答案:

答案 0 :(得分:0)

根据我的评论,当您从A读取时需要同步,因为它会强制线程之间的内存一致性。在没有同步的情况下,某些线程x可以对某个变量B进行更改,而另一个线程x不需要将更改视为synchronized (data) { /* look at what's in data.listClient */ }。同步强制线程查看对共享内存的更改。

从技术上讲,这是因为CPU有一个本地缓存,它临时存储变量。同步强制CPU从主内存加载变量,而不是查看可能过时的缓存。

因此,listClient强制读者线程看到在同步方法newClient期间对synchronized (this)所做的任何更改。 (同步实例方法与size相同。)

从你的描述中,听起来读者线程看到列表的{{1}}增加但从未看到对支持数组的更改。