猿问

异步情况下的循环,怎么解决这个问题

我的需求就是在android 中,需要异步上传一批图片检测,但是结果要按顺序加入list中,相当于调用方法有序,但回调无序,如何解决?


下面是模拟代码,如何实现在新建线程的情况下保证list.add方法正常,按序执行


public class Test {

    public static void main(String args[]) {

        for (int i = 0; i < 10; ++i) {

            test1(i);

        }

    }


    static List<String> arrayList = new ArrayList<>();


    private static void test1(final int i) {

        new Thread(new Runnable() {

            @Override

            public void run() {

                try {

                    arrayList.add(i, i + "position");

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        }).start();

    }

}


Smart猫小萌
浏览 556回答 6
6回答

慕桂英3389331

用synchronized关键字

胡子哥哥

今天刚刚看过并发编程实战关于可变对象的安全发布与访问:安全发布:在静态初始化函数中初始化一个对象引用;将对象的引用保存在volatile或AtomicReference上将对象的引用保存到某个正确构造对象的final类型上将对象保存在一个锁的范围内.安全访问:线程封闭只读共享线程安全共享, 该发布对象内部的访问方式是线程安全的, 就不需要外部同步了保护对象, 发布可变对象的对象通过限制外界的访问, 指定访问可变对象的接口.static List<String> arrayList = new ArrayList<>();这样已经符合了安全发布的第一条那么就要保证安全访问了, 由于list肯定不能安全访问的前三种情况, 那么只能依靠在发布对象时,限制外界的访问, 也就是加锁.

守候你守候我

用线程池的invokeAll方法,可以保证结果的顺序和传入参数的顺序一致

缥缈止盈

public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; ExecutorService exec = Executors.newFixedThreadPool(10);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; List<Callable<Integer>> list = new ArrayList<>();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 10; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list.add(newTask(i));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (Future<Integer> future : exec.invokeAll(list)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(future.get());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (ExecutionException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; exec.shutdown();&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; static Callable<Integer> newTask(final int t) {&nbsp; &nbsp; &nbsp; &nbsp; return new Callable<Integer>() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public Integer call() throws Exception {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("newTask: " + t);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep((10 - t) * 1000);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return t;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }
随时随地看视频慕课网APP

相关分类

Java
我要回答