多线程实现的几种方式
1.继承Thread类,重写run方法。
2.实现Runnable,实现run方法。
3.实现Callable接口。
4.实现有返回结果的线程,使用ExecutorService、Callable、Future实现返回结果的线程。
Volatile的作用
1.volatile可以保证线程一致性:禁止指令重排序。
2.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。
Volatile与Synchronized比较
1.Volatile是轻量级的synchronized,因为她不会引起上下文的切换和调度,所以Volatile性能更好。
2.Volatile只能修饰变量,synchronized可以修饰方法,静态方法,代码块。
3.Volatile对任意单个变量的读/写具有原子性,但是类似于i++这种复核操作不具有原子性。而锁的互斥执行的特性可以确保对整个临界区代码执行具有原子性。
4.多线程访问volatile不会发生阻塞,而synchronized会发生阻塞。
5.volatile是变量在多线程之间的可见性,synchronized是多线程之间访问资源的同步性。
synchronized锁的升级顺序
锁解决了数据的安全性,但是同样带来了性能的下降。hostpst虚拟机的作者经过调查发现,大部分情况下,加锁的代码不仅仅不存在多线程竞争,而且总是由同一个线程多次获得。所以基于这样一个概率,synchronized在JDK1.6之后做了一些优化,为了减少获得锁和释放锁的性能开销,引入偏向锁、轻量级锁、自旋锁、重量级锁,锁的状态根据竞争激烈的程度从低到高不断升级。
锁主要存在四种状态,依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态。
锁的升级过程,首先是无锁的状态,当有一个线程访问同步块时,升级成偏向锁,当有锁竞争时候由偏向锁升级为轻量级锁,锁自旋十次失败后,锁升级为重量级锁。