线程
线程安全:同步(多线程间访问数据一致性)是目的,互斥是手段
线程的状态有:
- new:新创建的线程
- Ready:准备就绪的线程,由于CPU分配的时间片的关系,此时的任务不在执行过程中。
- Running:正在执行的任务
- Block:被阻塞的任务
- Time Waiting:计时等待的任务
- Terminated:终止的任务
同步
阻塞
- synchronized关键字
作用于代码块:需要自己指定加锁对象,锁对象包括对象本身、对象的Class和其他对象。对给定对象加锁,进入同步代码前要获取给定对象的锁。
直接作用于实例方法:相当于给当前实例加锁,进入同步代码块前要获得当前实例的锁。
直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获取当前类的锁。
- ReentrantLock 方法,可实现公平锁和费公平锁,Sync来实现NoFairSync和FairSync
- ReentrantReadWriteLocK
- 利用Java的通知等等机制,Object.wait()和还有Object.notify()。wait方法既释放cpu,又释放锁。 sleep方法只释放cpu,但是不释放锁。
- Semaphore,Semaphore.acquire()和Semaphore.release()
- CountDownLatch
- CyclicBarrier
不阻塞
基于冲突检测的乐观并发策略,缺点 循环开销大;优点 比锁强大很多
- CAS 乐观锁,AtomicInteger
- AQS 即AbstractQueuedSynchronizer, 队列同步器,AQS的实现依赖内部的同步队列(FIFO双向队列)
不同步
- ReentrantLock AQS队列
- ThreadLocal
线程池
Android提供了四种常用的操作多线程的方式,分别是:
- Handler+Thread
- AsyncTask
- ThreadPoolExecutor
- IntentService
线程池
public ThreadPoolExecutor (
int corePoolSize, // 核心线程数量
int maximumPoolSize, // 最大线程数(核心线程数 + 临时线程数)
long keepAliveTime, // 临时线程的最大空闲时间
TimeUnit unit, // 时间单位(针对临时线程)
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 线程工厂(可以为线程起名字),线程池中的线程默认名称为pool-m-thread-n
RejectedExecutionHandler handler // 拒绝策略
)
线程池分为四个类型:
- CachedThreadPool:闲置线程超时会释放,没有闲置线程的情况下,每次都会创建新的线程。
- FixedThreadPool:线程池只能存放指定数量的线程池,线程不会释放,可重复利用。
- SingleThreadExecutor:单线程的线程池。
- ScheduledThreadPool:可定时和重复执行的线程池。
多线程执行任务的流程
- 简而言之:
- 任务来了,优先考虑核心线程。
- 核心线程满了,进入阻塞队列。
- 阻塞队列满了,考虑非核心线程。
- 非核心线程满了,再触发拒绝任务。