1.如何保证线程顺序执行?
1)使用 join() 方法;2)使用 Executors.newSingleThreadExecutor();
2.Volatile和synchronized
JMM(Java Memory Model):Java内存模型,并发过程中处理内存可见性、原子性、有序性的问题
1)并发编程的两个关键性问题:
a.线程之间如何通信:(wait()、notify()、notifyall())
隐式通信-内存共享;显式通信-消息传递
b.线程间如何同步
在共享内存的并发模型中,同步是显示做的:synchronized
在消息传递的并发模型中,由于消息的发送必须在消息接收之前,所以同步是隐式的
2)定位内存可见性问题
首先,需明确什么对象是内存共享的,什么不是
volatile:原子性、可见性;不能做到复合操作的;开销小
1)对于声明了volatile的变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,会把这个变量所在缓存行的数据写回到系统内存(主存)
2)在多处理器的情况下,保证各个处理器缓存一致性的特点,就会实现缓存一致性协议(每个处理器通过show看到总线上传播的数据来检测自己缓存的值是否过期,当处理器发现自己缓存的值的内存地址被修改后,会将自己当前处理器的值设置为失效状态,当对这个数据进行修改的时候,会重新从主存读取到自己的缓存里)
synchronized:可重入锁、互斥性、可见性
先通过monitor.Enter获取monitor(监视器),当获取成功后获得该Object,处理逻辑完毕/线程执行出现异常后 执行monitor.Exit释放锁;如获取失败会进入synchronizedQueue队列,当执行完monitor.Exit后有一个通知让这个队列出队列重新获取。
3.Lock
可以主动释放锁。
ReadWriteLock读写锁:ReadLock、WriteLock。
ReentrantLock:可重入锁。
可中断锁
公平锁
ReentranReadWritetLock:可重入读写锁 。