for循环问题
1、遍历时内做移除操作。
private ArrayList<OnOffsetChangedListener> listeners = new ArrayList<>(); public void startRemove(View view) { //话说这种写法可以减少计算数组大小的次数,可以提升性能。可是如果数组是变动的,那么这种写法一定有问题要么越界,要么遍历不全。 int length = listeners.size(); for (int i =0; i<length; i++){ listeners.get(i).onOffsetChanged(); } } public void startRemove(View view) { for (int i =0; i<listeners.size(); i++){ listeners.get(i).onOffsetChanged();//如果这里是移除操作,一定崩溃。 } } //这样可以避免越界,但是限于单线程使用。 public void startRemove(View view) { ArrayList<OnOffsetChangedListener> lists = (ArrayList<OnOffsetChangedListener>) listeners.clone(); for (int i =0; i<lists.size(); i++){ lists.get(i).onOffsetChanged(); } }
//使用volatile修饰 private volatile ArrayList<OnOffsetChangedListener> listeners = new ArrayList<>(); public void startRemove(View view) { new Thread(new Runnable() { @Override public void run() { for (int i =0; i<listeners.size(); i++){ Logger.d("tangzy", "i2 = "+i); listeners.get(i).onOffsetChanged(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new Thread(new Runnable() { @Override public void run() { for (int i =listeners.size()-1; i>=0; i--){ Logger.d("tangzy", "i = "+i+", "+listeners.get(i).getClass().getName()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); Logger.d("tangzy", "listeners = "+listeners.size()); }
2、遍历时,可能会有其他访问做移除操作。