Java 多线程(一) 基本多线程用法
Thread
基本用法:
|
|
其中 runable 是一个 Runnable 对象, 只需要用以下方式创建并在其中填入方法即可:
|
|
在 Java8, 事实上我们可以使用 lambda 语法
|
|
结合一下:
|
|
相关方法如下, 下面 run 和 join 看起来一样, 实际上:
run 就是你放下手头事情去修手机,修完继续工作, start 之后 join, 就相当于你把手机给别人去修, 然后等到什么时候工作需要手机了, 你执行 join 方法, 等到手机修好或者手机已经修好了, 继续工作.
|
|
另外还有个方法: Thread.sleep(), 字面意思, 阻塞当前线程, 可以填入阻塞多少毫秒, 然后没了
其余方法就相对简单或者没必要了解了(作为 Android 工程师的话), 跳过. 事实上做 Android 估计是很少用到Thread 这种底层的 api 了, 我更多会使用协程或者 Executor, 也可也适当考虑 Handler.
Executor
Executor 是 Java 的一个线程工具, 一个接口, 其中只有一个方法 execute, 绝大多数情况下我们如果要使用, 需要使用其实现类 ExecutorService
|
|
那它怎么用呢? 首先我们需要创建一个 Executor, 然后传入 runnable 就行了
|
|
其实你也可以自己去实现 Executor 接口, 但是使用又不是很方便, 直接从 Executors 里面取它不香吗? 具体详见 Executor 接口上面的注释
不过需要注意的是使用上面方法创建出来的 Executor 并不会立即停止, 以方便之后进来的线程重用部分对象, 避免内存抖动. 不过其实这只是个入口方法罢了, 点开内部我们可以看到:
|
|
Executors 里面还有很多其他方法, 就不一一例举了, 必要性不大, 举几个:
|
|
那么问题来了, 我们创建的线程如果永不自动关闭, 那应该怎么办呢? 其实有如下 api
|
|
Handler
-
干啥的: 在指定的运行中的线程执行任务
-
Looper: 就是个死循环
-
prepare(): 通过 ThreadLocal 创建一个 Looper
-
loop(): 取出 Looper 对象中的MessageQueue进行消息循环
Message 本身其实是个链表, 有 what / arg1 / arg2 / obj / callback / next等
-
-
分发消息: 先看 Message 有没有 callback 其次调用 handleMessage 最后查看子类是否 override handleMessage
|
|
有个坑: Handler 容易内存泄露, 但事实上所有的内部类都会这样, 此时我们应该选择持有外部类的弱引用并使用 WeakReference<>.get()
来调用并判断是否为 null