Java 在ArrayList线程安全上移动对象的最佳方式是什么?
我在Android中使用一个外部库,它有一个从另一个线程访问的对象的ArrayList。我的问题是,我想以一种不会在另一个线程上导致null异常的方式从这个AarrayList中移动一些对象 所以,我想做的是:我有一个ArrayList ABCDEFGH,我想把F从它的实际位置移到第一个位置,这样ArrayList就会变成FABCDEGH。注意,我不能使用swap,因为其他对象都向右移动 一个简单的实现是:Java 在ArrayList线程安全上移动对象的最佳方式是什么?,java,android,Java,Android,我在Android中使用一个外部库,它有一个从另一个线程访问的对象的ArrayList。我的问题是,我想以一种不会在另一个线程上导致null异常的方式从这个AarrayList中移动一些对象 所以,我想做的是:我有一个ArrayList ABCDEFGH,我想把F从它的实际位置移到第一个位置,这样ArrayList就会变成FABCDEGH。注意,我不能使用swap,因为其他对象都向右移动 一个简单的实现是: list.remove(F); list.add(0,F); 但此实现会在另一个线程上
list.remove(F);
list.add(0,F);
但此实现会在另一个线程上导致null异常,因为另一个线程正在通过手写计数循环循环列表,因此由于竞争条件,线程循环可以在删除和添加F之间运行。我无法使ArrayList线程安全,因为我没有访问外部库的权限
有没有更好的方法在没有竞争条件的情况下进行此移动(从Arraylist的任何位置移动到Arraylist的任何位置)?请注意,不会修改ArrayList的大小。如果您拥有循环和交换代码,则可以同步列表上的两个操作
// code for loop
for (int i = 0; i < length; i++) {
synchronized(list) {
letter = list.get(i);
}
// whatever else
}
// code for swap
synchronized(list) {
list.remove(F);
list.add(0,F);
}
如果您拥有循环和交换代码,则可以同步列表上的两个操作
// code for loop
for (int i = 0; i < length; i++) {
synchronized(list) {
letter = list.get(i);
}
// whatever else
}
// code for swap
synchronized(list) {
list.remove(F);
list.add(0,F);
}
重新排列ArrayList中的对象,但不要使用
add()
、remove()
或任何其他可能改变大小的方法
可以这样做,相当不雅观,如下所示:
Object temp = F;
for (int i = list.indexOf(F); i > 0; i--) {
list.set(i, list.get(i - 1));
}
list.set(0, temp);
但是,请注意,另一个线程中的循环可能会遇到顺序错误的对象,或者在不同位置遇到相同的对象。如果另一个线程添加或删除项目,那么这将不起作用
我认为如果无法同步列表,可能不应该尝试从线程中修改它。在ArrayList中重新排序对象,但不使用
add()
、remove()
或任何其他可能改变大小的方法
可以这样做,相当不雅观,如下所示:
Object temp = F;
for (int i = list.indexOf(F); i > 0; i--) {
list.set(i, list.get(i - 1));
}
list.set(0, temp);
但是,请注意,另一个线程中的循环可能会遇到顺序错误的对象,或者在不同位置遇到相同的对象。如果另一个线程添加或删除项目,那么这将不起作用
我认为如果您无法同步列表,您可能不应该尝试从线程中修改它。您是否拥有执行循环和删除/添加的代码?或者循环在库代码中运行?循环在库代码中运行您拥有执行循环和删除/添加的代码吗?或者循环在库代码中运行?循环在库代码中运行Hi sudocode,我不拥有循环代码,只有交换(这是一个移动,不是交换)。如果我只同步交换,我是否仍然具有竞争条件?谢谢如果你没有循环代码,并且它没有在列表上同步,那么你就不能在你自己的线程上安全地更改列表。嗨,sudocode,我没有循环代码,只有交换(这是一个移动,不是交换)。如果我只同步交换,我是否仍然具有竞争条件?谢谢如果您没有循环代码,并且它没有在列表上同步,那么您就无法在自己的线程上安全地更改列表。