Java线程无法读取主线程写入的数据的更改?

问题描述 投票:0回答:1

我有一堂课

Notif
(是的,我知道属性不应该公开):

class Notif {
        public int found;
        public String reply;

        public Notif(int i){
                found = i;
        }
}

我在主线程中实例化一个:

Notif[] notif = new Notif[] {new Notif(0)};

然后我将其传递给另一个线程:

 Thread tS = new Thread(new InputSearch(input, notif, neighbors, selfNum));                                              tS.start();

我在主线程中更改其属性:

 notif[0].reply = "File " + msgs[i].fName + " found in " + msgs[i].Cx + ". - Computer " + nums.get(i);
 notif[0].found = 1;
 System.out.println("found w");

它应该读取

tS
线程中的值(
InputSearch
run()
的片段):

 while(System.currentTimeMillis() - start < hopCt*2000) {
         if(notif[0].found != 0){
                System.out.println("found n");
                replies.add(notif[0].reply);
                notif[0].found = 0;
          }
 }
 if(replies.size() == 0)
           System.out.println("No replies in " + hopCt*2 + " seconds.");

对于输出,我只得到

found w
而不是
found n
No replies in x seconds.
也会出现。 我希望
found w
found n
都会出现,并且
No replies in x seconds.
不会打印。

notif.reply
notif.found
已更改,但
tS
线程似乎没有读取新值?

java multithreading java-threads
1个回答
0
投票

我在主线程中更改其属性:

这使得你的代码不线程安全

一个问题是可见性,根据Java内存模型。当您更改引用变量的值时,例如切换

String
引用的
reply
对象,该更改保证能被其他线程看到。

一种解决方案是使用

AtomicReference
作为访问实际有效负载(新的
String
对象)的中间层。

© www.soinside.com 2019 - 2024. All rights reserved.