使用线程更新ArrayList对象实例的好方法是什么?

时间:2016-12-05 16:33:29

标签: java multithreading sockets arraylist reference

我正在开发一个项目,对于我的项目的一部分,我有作为字符串的ArrayList,我保持记录,以保持来自其他互连系统的传入消息。这是一个点对点设计,所以我想让BufferedReader准备好读取从任何套接字发送到系统的任何消息,所以我设计了一个线程,在创建时,为每个套接字创建一个新线程,用于监听特定输入流。

现在我尝试使用以下两个私有类:

InputListener(内部类ListenerThread)

private class InputListener implements Runnable{
        private ArrayList<String> queue;
        private ArrayList<Stream> sockets;
        private ArrayList<Thread> threads;
        public InputListener(ArrayList<String> q, ArrayList<Stream> s)
        {
            this.queue = q;
            this.sockets = s;
            this.threads = new ArrayList<Thread>();
            for(int i = 0; i < this.sockets.size(); i++)
            {
                Thread t = new Thread(new ListeningThread(this.sockets.get(i).is, this.queue));
                t.start();
                threads.add(t);
            }
        }
        private class ListeningThread implements Runnable{
            private BufferedReader read;
            private ArrayList<String> queue;
            private boolean status;
            public ListeningThread(InputStream is, ArrayList<String> q)
            {
                this.read = new BufferedReader(new InputStreamReader(is));
                this.queue = q;
                status = true;
            }
            @Override
            public void run() {
                while(true)
                {
                    String str = "";
                    try {
                        str += read.readLine();
                        while(!str.equals("END"))
                            str += read.readLine();
                        this.queue.add(str);
                    } catch (IOException e) {
                    status = false;
                    break;
                }
            }
        }
    }
    @Override
    public void run() {
        while(status)
            ;
    }
}

private class Stream{
    public InputStream is;
    public OutputStream os;
    public Stream(final Socket s)
    {
        try {
            this.is = s.getInputStream();
            this.os = s.getOutputStream();              
        } catch (IOException e) {
            return;
        }
    }

    public InputStreamReader getReader()
    {
        return new InputStreamReader(this.is);
    }

}

当我创建InputListener时,我从另一个类传递对队列的引用,我排除了这个类以防止过度复杂化这个问题,所以假设这个ArrayList被初始化并且它的指针(我不记得是什么) java调用它)传递。我的问题是,当我使用如下所示的循环时,我只是陷入无限循环

while(queue.size equals 0)
   Do nothing

Remove and do something with String at index 0 in queue

任何人都可以帮我解决这个问题吗?任何帮助都会受到很大关注!

1 个答案:

答案 0 :(得分:1)

您应该使用java.util.concurrent中的一个专用容器类,而不是标准的非同步ArrayList。

例如,LinkedBlockingQueue

// in the setup
BlockingQueue<String> queue = new LinkedBlockingQueue<>();

// in producer thread
queue.put(work);

// in consumer thread
work = queue.take(); // blocking - waits as long as needed

我还建议您阅读Concurrency上的Java教程。这不是一个微不足道的主题。