Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在ArrayList线程安全上移动对象的最佳方式是什么?_Java_Android - Fatal编程技术网

Java 在ArrayList线程安全上移动对象的最佳方式是什么?

Java 在ArrayList线程安全上移动对象的最佳方式是什么?,java,android,Java,Android,我在Android中使用一个外部库,它有一个从另一个线程访问的对象的ArrayList。我的问题是,我想以一种不会在另一个线程上导致null异常的方式从这个AarrayList中移动一些对象 所以,我想做的是:我有一个ArrayList ABCDEFGH,我想把F从它的实际位置移到第一个位置,这样ArrayList就会变成FABCDEGH。注意,我不能使用swap,因为其他对象都向右移动 一个简单的实现是: list.remove(F); list.add(0,F); 但此实现会在另一个线程上

我在Android中使用一个外部库,它有一个从另一个线程访问的对象的ArrayList。我的问题是,我想以一种不会在另一个线程上导致null异常的方式从这个AarrayList中移动一些对象

所以,我想做的是:我有一个ArrayList ABCDEFGH,我想把F从它的实际位置移到第一个位置,这样ArrayList就会变成FABCDEGH。注意,我不能使用swap,因为其他对象都向右移动

一个简单的实现是:

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,我没有循环代码,只有交换(这是一个移动,不是交换)。如果我只同步交换,我是否仍然具有竞争条件?谢谢如果您没有循环代码,并且它没有在列表上同步,那么您就无法在自己的线程上安全地更改列表。