简体   繁体   English

无法使用volatile在线程之间共享列表值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM