[英]Cannot share List value between threads using volatile
The server is initialized then thread started. 服务器初始化,然后启动线程。 The thread writes to
List<String> JSON_LIST
. 该线程将写入
List<String> JSON_LIST
。 When http request comes to parent thread it shows that JSON_LIST
is empty however other thread have already added new element. 当http请求到达父线程时,它表明
JSON_LIST
为空,但是其他线程已经添加了新元素。 Why volatile is not working? 为什么volatile不起作用?
import com.sun.net.httpserver.HttpServer;
import com.sun.jersey.api.container.httpserver.HttpServerFactory;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
public class HelloWorld extends Thread {
@GET
@Produces("text/plain")
public String getClichedMessage() {
// Return some cliched textual content
return JSON_LIST.get(JSON_LIST.size() - 1);
}
private volatile List<String> JSON_LIST = new ArrayList<String>();
public void addJSONRecord(String s){
JSON_LIST.add(s);
}
@Override
public void run() {
addJSONRecord(json);
}
public static void main(String[] args) throws IOException {
HttpServer server = HttpServerFactory.create("http://localhost:8080/");
server.start();
(new HelloWorld()).start();
System.out.println("Server running");
System.out.println("Visit: http://localhost:8080/service");
System.out.println("Hit return to stop...");
System.in.read();
System.out.println("Stopping server");
server.stop(0);
System.out.println("Server stopped");
}
UPDATE UPDATE
I have one class. 我有一堂课。 It should acts as web server.
它应该充当Web服务器。 Additional theread was created to populate JSON_LIST with records.
创建了额外的theread以用记录填充JSON_LIST。 The problem is when I try to
return JSON_LIST.get(JSON_LIST.size() - 1)
it always returns ArrayindexOutOfBound exception. 问题是当我尝试
return JSON_LIST.get(JSON_LIST.size() - 1)
它总是返回ArrayindexOutOfBound异常。 Therefore, Jersey thread cannot see updates made to private volatile List<String> JSON_LIST
. 因此,Jersey线程无法查看对
private volatile List<String> JSON_LIST
。
How to fix it? 如何解决?
UPDATE2: UPDATE2:
I have tried several things: 我尝试了几件事:
private volatile CopyOnWriteArrayList<String> JSON_LIST = new CopyOnWriteArrayList<String>();
and 和
public String getClichedMessage() {
synchronized (JSON_LIST){
return JSON_LIST.get(JSON_LIST.size() - 1);
}
}
public void addJSONRecord(String s){
synchronized (JSON_LIST){
JSON_LIST.add(s);
}
}
Nothing solved the problem 什么都没解决问题
Because volatile only guarantees the visibility of a new value of JSON_LIST. 因为volatile仅保证新值JSON_LIST的可见性。 Ie, it guarantees that, if you assign a new list to the JSON_LIST variable in thread A, thread B will see the new value of the variable.
即,它保证了,如果您在线程A中为JSON_LIST变量分配新列表,则线程B将看到该变量的新值。
Changes to the list referenced by the variable are not made thread-safe by volatile. volatile不会使对变量引用的列表的更改成为线程安全的。 You need a thread-safe list to have such a guarantee, or you need to synchronize every access to the list.
您需要一个线程安全列表来获得这种保证,或者需要同步对列表的每次访问。
EDIT: 编辑:
reading your code again, this seems more than a concurrency problem. 再次阅读您的代码,这似乎不仅仅是并发问题。 Jersey doesn't use the same HelloWorld instance than the one you explicitely create and start in your main method.
Jersey所使用的HelloWorld实例与您在main方法中显式创建并启动的实例不同。 So your main method adds in a list, and Jersey reads in another one.
因此,您的主要方法会添加一个列表,Jersey会读取另一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.