为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Smart猫小萌 2019-03-29 19:19:54
我的需求就是在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();    }}
查看完整描述

6 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

synchronized关键字


查看完整回答
反对 回复 2019-04-25
?
胡子哥哥

TA贡献1825条经验 获得超6个赞

今天刚刚看过并发编程实战关于可变对象的安全发布与访问:
安全发布:

  1. 在静态初始化函数中初始化一个对象引用;

  2. 将对象的引用保存在volatile或AtomicReference上

  3. 将对象的引用保存到某个正确构造对象的final类型上

  4. 将对象保存在一个锁的范围内.

安全访问:

  1. 线程封闭

  2. 只读共享

  3. 线程安全共享, 该发布对象内部的访问方式是线程安全的, 就不需要外部同步了

  4. 保护对象, 发布可变对象的对象通过限制外界的访问, 指定访问可变对象的接口.

static List<String> arrayList = new ArrayList<>();这样已经符合了安全发布的第一条
那么就要保证安全访问了, 由于list肯定不能安全访问的前三种情况, 那么只能依靠在发布对象时,限制外界的访问, 也就是加锁.


查看完整回答
反对 回复 2019-04-25
?
守候你守候我

TA贡献1802条经验 获得超10个赞

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


查看完整回答
反对 回复 2019-04-25
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

public static void main(String[] args) {

        ExecutorService exec = Executors.newFixedThreadPool(10);

        

        List<Callable<Integer>> list = new ArrayList<>();

        

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

            list.add(newTask(i));

        }

        

        try {

            for (Future<Integer> future : exec.invokeAll(list)) {

                try {

                    System.out.println(future.get());

                } catch (ExecutionException e) {

                    e.printStackTrace();

                }

            }

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        exec.shutdown();

    }

    

    static Callable<Integer> newTask(final int t) {

        return new Callable<Integer>() {

            @Override

            public Integer call() throws Exception {

                System.out.println("newTask: " + t);

                try {

                    Thread.sleep((10 - t) * 1000);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

                return t;

            }

        }

    }


查看完整回答
反对 回复 2019-04-25
  • 6 回答
  • 0 关注
  • 555 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号