学习笔记

156 阅读2分钟

多线程

1.为什么调用Object.wait()方法经常需要外面包着while()循环?

因为在多个线程抢占锁的时候竞态条件可能会发生改变,所以在获得锁之后就需要再次判断条件是否改变.

例如在生产消费者模型中,消费者A和B进行wait()阻塞,生产出一个产品之后notifyall(),此时满足条件"有产品",假设A拿到锁消耗掉了产品,之后再notifyall()通知B,如果用if的话A拿到产品之前满足条件,此时B再去拿产品满足条件但是实际上并没有产品,产生空指针异常,用while循环判断是否有产品就不会有问题.

2.同样是持有外部activity的引用, 为什么AsyncTask会导致内存泄漏,而View就不会?

内存泄露的根本原因是一个长生命周期的对象持有一个短生命周期的对象,造成短生命周期对象没办法被回收所导致的.

AsyncTask会导致内存泄露是由于任务都是串行执行,如果某个任务比较耗时或者有太多的任务需要处理,导致线程还持有activity的引用,导致activity无法回收导致内存泄露. view会持有context的引用,不会导致内存泄露是因为它的生命周期比activity短,除非是静态的view.

View

聊聊你对子线程不能更新ui的看法

子线程不能更新ui吗?

是的.

绝对吗?

我看未必.

在onCreat()中新建线程可以成功更新ui.但是sleep一段时间就会报错. 报错来源是ViewRootImpl的checkThread()方法.

ViewRootImpl会调用用checkThread()方法去检查当前访问UI的线程是否为创建UI的那个线程,不是的话就会抛出异常.

onCreat()时能成功是因为当时ViewRootImpl还没创建.并且更新操作已经将值赋上,等ViewRootImpl创建之后就能更新.

不过在onCreat()中创建子线程太极端了,一般不会去做