从Thread修改Global ArrayList

时间:2013-03-18 15:08:32

标签: java android multithreading

我要做的是修改一个线程内的全局ArrayList,并在我的Thread之外修改这个ArrayList。

这是我的代码,它可以工作但是当我从外面读取我的ArrayList时,它有一个正确的大小但是这个ArrayList中的所有元素都是最后添加的,我的意思是如果最后一个元素有pollingCode,pollingType,polling Value = 0 ,数组中的所有元素都具有相同的值。

有人知道为什么会这样吗?

public abstract class OverlayView extends RelativeLayout {

protected ArrayList<InputEvent> eventList       = new ArrayList<InputEvent>();

public void StartEventMonitor() {
        Thread b = new Thread(new Runnable() {

                public void run() {

                    InputEvent ie= new InputEvent();
                    while (m_bMonitorOn) {
                        for (InputDevice idev:events.m_Devs) {
                            // Open more devices to see their messages

                            int pollingEvent = idev.getPollingEvent();

                                int pollingType=idev.getSuccessfulPollingType();
                                int pollingCode=idev.getSuccessfulPollingCode();
                                int pollingValue=idev.getSuccessfulPollingValue();

                                final String line =/* idev.getName()+
                                        ": " +*/ idev.getSuccessfulPollingType()+
                                        " " + idev.getSuccessfulPollingCode() + 
                                        " " + idev.getSuccessfulPollingValue() +
                                        "\n";
                                Log.d(LT, "Event:"+line);

                                ie.setCode(pollingCode);
                                ie.setType(pollingType);
                                ie.setValue(pollingValue);
                                eventList.add(ie);
                            }

                        }
                    }
                }
            });
            b.start();    
   }

}

4 个答案:

答案 0 :(得分:2)

您是否尝试在循环中创建新的InputEvent。您只有一个即添加列表,只需更新InputEvent上的值:

InputEvent ie= new InputEvent();
while (m_bMonitorOn) {
    ie= new InputEvent();
 ...

答案 1 :(得分:2)

这只是一个与多线程无关的FYI。

您正在重复使用相同的InputEvent对象。所以你调用setCode调用同一个InputEvent的setCode方法。添加只是每次都会添加相同的IE实例。

例如,尝试(假设列表大小> 1)

if(eventList.get(0) == eventList.get(1)){
   //re using the same object
}

您应该在for循环中移动InputEvent的创建分配。

答案 2 :(得分:2)

不在所有细节中研究代码:您的列表不是线程安全的。我建议您使用类似ArrayBlockingQueue的内容来共享线程之间的事件。这将消除重大问题,无论如何都是正确的事情。

答案 3 :(得分:0)

你有2个错误:

首先,改变:

protected ArrayList<InputEvent> eventList = new ArrayList<InputEvent>();

protected final List<InputEvent> eventList = 
    Collections.synchronizedList(new ArrayList<InputEvent>());

这将使得从List线程安全地添加和删除项目。现在我们需要修复添加项目的问题。对于每个事件,您都需要新的InputEvent实例。所以按照以下方式改变你的循环:

public void run() {
    while (m_bMonitorOn) {
        for (InputDevice idev:events.m_Devs) {
            InputEvent ie= new InputEvent();
               ...
            eventList.add(ie);
        }
    }
}