线程与异步
2022-06-07 本文已影响0人
carlwu_186
synchronized 和Lock区别
锁类型
- 可重入锁:在执行对象中所有同步方法不用再次获得锁。
- 可中断锁:在等待获取锁过程中可中断。
- 公平锁:按等待获取锁的等待时间进行获取,等待时间长的具有优先获取锁权利。
-
读写锁:对资源读取和写入的时候拆分为2部分处理,读的时候可以多线程一起读,写的时候必须同步地写。
synchronize和Lock对比
Thread
- 对目标线程调用interrupt()方法可以请求中断一个线程,目标线程通过检测isInterrupted()标志获取自身是否已中断。如果目标线程处于等待状态,该线程会捕获到InterruptedException;目标线程检测到isInterrupted()为true或者捕获了InterruptedException都应该立刻结束自身线程;
- 也可以通过标记为判断线程是否退出线程,标志位判断需要正确使用volatile关键字;在Java虚拟机中,变量的值保存在主内存中,但是,当线程访问变量时,它会先获取一个副本,并保存在自己的工作内存中。如果线程修改了变量的值,虚拟机会在某个时刻把修改后的值回写到主内存,但是,这个时间是不确定的!volatile关键字的目的是告诉虚拟机:
- 每次访问变量时,总是获取主内存的最新值;
- 每次修改变量后,立刻回写到主内存。
volatile关键字解决的是可见性问题:当一个线程修改了某个共享变量的值,其他线程能够立刻看到修改后的值。
- 守护线程是指为其他线程服务的线程。在JVM中,所有非守护线程都执行完毕后,无论有没有守护线程,虚拟机都会自动退出。在守护线程中,编写代码要注意:守护线程不能持有任何需要关闭的资源,例如打开文件等,因为虚拟机退出时,守护线程没有任何机会来关闭文件,这会导致数据丢失。
- JVM规范定义了几种原子操作:
- 基本类型(long和double除外)赋值,例如:int n = m;
- 引用类型赋值,例如:List<String> list = anotherList。
long和double是64位数据,JVM没有明确规定64位赋值操作是不是一个原子操作,不过在x64平台的JVM是把long和double的赋值作为原子操作实现的。
- wait和notify用于多线程协调运行:
- 在synchronized内部可以调用wait()使线程进入等待状态;
- 必须在已获得的锁对象上调用wait()方法;
- 在synchronized内部可以调用notify()或notifyAll()唤醒其他等待线程;
- 必须在已获得的锁对象上调用notify()或notifyAll()方法;
- 已唤醒的线程还需要重新获得锁后才能继续执行。
- ReentrantLock可以替代synchronized进行同步;必须先获取到锁,再进入try {...}代码块,最后使用finally保证释放锁;Condition可以替代wait和notify;