本文最后更新于163 天前,其中的信息可能已经过时,如有错误请发送邮件到3368129372@qq.com
基础代码
//创建锁
static final Object LOCK = new Object();
//执行
syncronized(LOCK){
//睡1s
LOCK.wait(1000L)
...
}
快速创建线程
Thread thread = new Thread(()->{
...
},t1)
LOCK.notify();
//随机唤醒一个加LOCK锁的wait线程
LOCK.notifyAll();
//唤醒全部的Lock中的wait线程
线程与进程
区别
- 进程是运行程序的实例,包含线程。
- 不同进程使用不同的内存空间,在当前进程下的所有线程可共享内存空间。
- 线程轻,上下文切换成本比进程切换成本低。
并行与并发
- 并发是根据时间片分给不同程序用。
- 并行是真的一起执行。
创建线程的方式
- 继承Thread类。
- 实现runnable接口
- 实现callable接口(有返回值且实现的run方法可以抛出异常)
- 线程池创建线程
//创建线程池对象 ExecutorService threadPool = Executors.newFixedThreadPool(3); //MyExecutors为实现Runnable接口的一个类 threadPool.submit(new MyExecutors()); //关闭线程池 threadPool.shutdown();
线程的状态
- NEW(新建)
- RUNNABLE(可执行,包括就绪和运行)
- BLOCK(阻塞)->得不到锁
- WAITING(等待)->调用wait()方法,需要等notify()了才能继续执行
- TIMED_WAITING->计时等待,调用了sleep()方法
- TERMINATED(结束)
wait与sleep的区别
- wait方法必须先获取锁(在外面加上Syncronized)
- wait在执行之后会释放锁(释放了之后仍然再执行waiting内的操作,但是外面家的syncronized不生效了而已),sleep如果在syncronized内执行则不会
线程池OOM
以下是一些可能导致OOM的线程池实现类的原因:
- FixedThreadPool 和 SingleThreadPool:
FixedThreadPool 和 SingleThreadPool 是固定大小的线程池,如果任务提交的速度过快,而线程池的大小又不够处理这些任务,就可能导致任务在队列中等待,最终耗尽内存。 - CachedThreadPool:
CachedThreadPool 是一个可缓存的线程池,会根据需要创建新的线程,但如果任务提交的速度超过了线程池的处理速度,可能会导致创建大量线程,消耗大量内存,最终导致OOM。 - ScheduledThreadPool:
ScheduledThreadPool 是用于定时执行任务的线程池,如果定时任务的执行时间过长,而且任务提交的速度过快,可能导致任务堆积,最终导致OOM。 - WorkManager:
在 Android 中,WorkManager 是用于管理后台任务的 API,如果后台任务的执行时间过长,或者任务提交速度过快,可能会导致内存耗尽。
防止线程池导致的内存溢出问题的一些解决方案包括:
- 合理设置线程池的大小,避免无限制地创建新线程。
- 使用有界的队列,以限制任务的排队数量。
- 调整任务的执行策略,避免任务耗时过长。
- 使用专门用于处理大量短时任务的线程池,例如ForkJoinPool。
线程池参数
CPU密集型:N+1,+1是为了防止某些线程不使用CPU了,就会CPU就会有多,多一个线程去压榨CPU
IO密集型:2N,与CPU消耗时间与IO消耗时间相关,更多为经验值。