【问题标题】:List of Thread and accessing another list线程列表和访问另一个列表
【发布时间】:2013-07-19 22:51:48
【问题描述】:

几分钟前我已经提出了另一个接近这个问题的问题,并且有很好的答案,但这不是我想要的,所以我试图更清楚一点。

假设我有一个类中的线程列表:

class Network {

    private List<Thread> tArray = new ArrayList<Thread>();
    private List<ObjectInputStream> input = new ArrayList<ObjectInputStream>();

    private void aMethod() {
        for(int i = 0; i < 10; i++) {
            Runnable r = new Runnable() {
                public void run() {
                    try {
                        String received = (String) input.get(****).readObject(); // I don't know what to put here instead of the ****
                        showReceived(received); // random method in Network class
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
            }
            tArray.add(new Thread(r));
            tArray.get(i).start();
        }
    }
}

我应该放什么来代替 ** ? 例如,tArray 列表的第一个线程只能访问输入列表的第一个输入。

编辑:假设我的输入列表已经有 10 个元素

【问题讨论】:

  • 也许this 会帮助你

标签: java arrays multithreading list


【解决方案1】:

如果你输入i,它会起作用。您还需要将ObjectInputStream 添加到每个线程的列表中。我建议您为此使用input.add。您还需要用一些线程填充tArray 列表,在那里再次使用添加。

【讨论】:

  • 是的,抱歉,我想假设输入列表已经归档。但是如果我用 i 而不是 ****,它就不会编译,因为当它退出循环时 i 将不存在,而不是线程
  • 你说的那个问题不存在。 i 被传递给编译器生成的构造函数,它应该保留在内部类中。错误信息到底是什么?
  • i 复制到循环内的 final 变量中,然后改用它:final int i2 = i;
  • 不能在不同方法中定义的内部类中引用非最终变量 i
  • @damo 这可能是个好主意,但是假设我出于某种原因必须删除线程(假设客户端断开连接并且我执行 tArray.remove(3), input.remove(3 )),问题是对于第 10 个客户端,i2 仍然具有相同的值,而实际上,它必须递减到 9,因为第 10 个客户端现在在列表中的第 9 位
【解决方案2】:

解决办法如下:

private void aMethod() {
    for(int i = 0; i < 10; i++) {
        final int index = i;  // Captures the value of i in a final varialbe.
        Runnable r = new Runnable() {
            public void run() {
                try {
                    String received = input.get(index).readObject().toString(); // Use te final variable to access the list.
                    showReceived(received); // random method in Network class
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            }
        };
        tArray.add(new Thread(r));
        tArray.get(i).start();
    }
}

由于您希望每个线程访问输入数组中的一个元素,您可以使用i 变量的值作为列表的索引。直接使用i 的问题是内部类无法从封闭范围访问非最终变量。为了克服这个问题,我们将i 分配给最终变量index。可以通过Runnable 的代码访问最终的index

其他修复:

  • readObject().toString()
  • catch(Exception exception)
  • tArray.add(new Thread(r))

【讨论】:

  • 糟糕,对错误感到抱歉。不幸的是,正如我告诉 damo 的那样,我不能做这样的事情,因为如果我出于某种原因必须删除一个线程(假设客户端断开连接并且我执行 tArray.remove(3)、input.remove(3)),那么问题就来了是对于第 10 个客户端,index 仍然具有相同的值,而事实上,它必须减少到 9,因为第 10 个客户端现在位于列表的第 9 位
猜你喜欢
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
相关资源
最近更新 更多