01-多线程
java thread
synchronized
-
类锁
- 修饰static函数和synchronized(ClassName.class)都是获取类锁
-
对象锁
- 修饰成员函数和synchronized(this|object)都是对象锁
- 其中修饰成员函数和synchronized(this)获取的都是当前类对象的锁
-
优点
- 简单,易用
- 开销少
-
缺点
- 可重入性差
- 大量使用可能导致性能下降
-
推荐用法
- 单例模式使用
- 用于计数器的自增或类似场景
Object.wait, Object.notify, Object.notifyAll
函数作用顾名思义
wait: 先释放对象锁,等待notify/notifyAll后释放
也就是说,可以基于他们实现条件变量, pv操作
native
- join: 让调用线程等待其结束
- yeild: 暂时让出时间片
- sleep: sleep
- interrupt: 打断执行
- 调用后,线程中的一些任务可能产生
InterruptedException
- interrupted(): 线程中判断是否被打断,若中断,返回true,并清除标志位(下一次一定返回false),
try-catch InterruptException
也会导致标志位清除 - isInterrupted(): 测试是否被打断,若中断,返回true,但不清除标志位(下一次一定返回与上一次相同)
- 调用后,线程中的一些任务可能产生
Callable
- 实现Callable,能获取返回状态
守护线程
在start()前,调用setDaemon(true)即可创建。类似于守护进程,是一直存在运行的线程。由于jvm的存在,若主线程退出,其他线程运行结束后会退出,
其他
-
ThreadLocal
- 相当于pthread的每线程存储
- 一个包装器,包装任何类型后,调用get,set方法,获取/修改当前线程中的值
-
java线程生命周期
GC Roots
在GC时,如何判断一个对象是否可回收,就是看其是否直接/间接被GC Roots引用,GC Roots一般包括
- 系统类加载器加载的类: Class: Classes loaded by a system class loader; contains references to static variables as well
- 当前栈中的对象: Stack Local: Local variables and parameters to methods stored on the local stack
- 活跃的线程: Active Java Threads: All active Java threads
- JNI(native代码)引用的对象: JNI References: Native code Java objects created for JNI calls; contains local variables,parameters to JNI methods, and global JNI references
Additionally, there are a few more possible types of GC Roots:
- 监视器监视的对象: Objects used as monitors for synchronization
- 由JVM实现定义的特定对象: Specific objects defined by the JVM implementation that are not garbage collected for its purpose. That might contain important exception classes, system class loaders, or custom class loaders
内存泄露
要注意内存泄露,非静态的内部类会持有外部的对象,若内部类是一个线程,则会导致外部对象(如Activity)无法释放,导致内存泄露
几种多线程工具的选择
-
AsyncTask(已弃用): 小而短的任务,后台任务需要推到前台
-
Executor: 推荐使用,后台任务执行,不需要推回前台
-
Handler: 可以把任务推到前台
-
HandlerThread: 把一个任务推到后台的一个线程中
-
Service: 不是线程,他是后台任务的活动空间(存后台任务的状态)
-
IntentService: 线程中使用context时
isInterrupted 和 interruptd
1 | public boolean isInterrupted() { |