多线程概览
线程的状态流转图
小记:
- java线程的优先级范围:0~10,值越大优先级越高,默认5
- 可运行状态的线程还需要获得CPU的时间片后才能运行
- ThreadLocal:每个线程有一个localValue存储ThreadLocal=>Object键值对,ThreadLocal.put数据的时候把自身作为key与value保存到localValue,get的时候在从localValue里取出
多线程和进程
- 线程依附于进程,每个进程可以有多个线程,每个线程只属于一个进程
- 进程拥有独立内存单元,互不干扰;一个进程里的多个线程共享内存
- 进程是资源分配的基本单位,线程是处理调度的基本单位
Thread和Runnable
- Runnale比Thread更具优势:避免单继承限制,Runnable更适合多线程去处理同一资源(一个Runnable实例多个Thread执行,Thread做不到 http://www.mamicode.com/info-detail-517008.html)
线程池
- newCachedThreadPool 无限线程 空闲回收 不够则创建
- newFixedThreadPool 控制最大并发数 有队列
- newScheduledThreadPool 控制最大并发数 有队列 有周期性
- newSingleThreadExecutor 只有一个线程
- shutdown:线程池置为关闭状态并intercept等待的线程;shutdownNow线程池置为关闭状态并intercept所有线程
线程常用操作
- yield wait sleep (yield sleep属于Thread方法,wait notify属于Object方法)
- wait:可以指定时间也可以不指定,不指定只能由notify、notifyAll唤醒。wait时线程释放执行权和锁
- notify/notifyAll 唤醒指定线程或所有线程(与wait配对,必须放在synchronized里否则抛运行时异常)
- sleep:必须指定时间,sleep时释放执行权但不释放锁
- yield:让步(进入可执行状态),暂停当前线程,让其他线程先走,下次线程调度程序调到又继续执行(不一定成功,因为让步后可能马上又被线程调度程序调起)
- interrupt:中断线程,清除解冻状态。sleep/wait都可以用interrupt打断,并抛出InterruptedException异常
- setDaemon():设置当前线程为守护线程或用户线程
A{B.join()}:两个线程需要都启动了才有效。A线程中调用B.join,会暂停A,执行B直到B执行结束后再执行A
经典消费者生产者实例
Queue<Integer> buffer = new LinkedList<>();
int maxSize = 10;
Thread producer = new Producer(buffer, maxSize, "PRODUCER");
Thread consumer = new Consumer(buffer, maxSize, "CONSUMER");
producer.start(); consumer.start();
同步锁
- synchronized(this) 锁住的是this 访问synchronized(this)代码块时,其他线程无法访问该对象中的所有synchronized(this)代码块及synchronized方法,其他代码块正常访问;
- synchronized方法锁 锁住的是该对象this 访问synchronized方法时,其他线程无法访问该对象中的所有synchronized方法及synchronized(this)代码块
- synchronized代码块 锁住是对象 只有对象中也锁住同一对象的代码块或方法才会互斥(使用该对象并不会互斥)
- class Log { log1(){synchronized(obj){…}} log2(){Log.d(“obj = “+obj)} }在AB两个线程中分别调用同一对象的log1 log2方法并不互斥,并行执行
- synchronized static 锁住的是类。而非静态方法锁住的是对象,所以二者不互斥
volatile与synchronized:volatile只修饰变量且不保证原子性(取值的时候会从CPU工作内存中取出刷新共享内存得到最新值)。volatile①保证此变量对所有线程的可见性②禁止指令重排序。synchronized 则可以使用在变量、方法、和类级别的。volatile性能比synchronized好,volatile比较适用于多线程对变量高并发的读操作
ps:这块主要的几种情况大致如上,建议根据这几种锁利用生产者消费者实例进行一个检验,这样有助理解。