面试题:
1. synchronized和volatile的区别
2. final,finally,finalize区别
1. synchronized和volatile的区别
1.1 JVM内存模型
JVM将内存组织分为主内存和工作内存两部分。
-
主内存
主内存包括方法区和堆。所有变量都存在主内存中,对于所有线程都是共享的。
-
工作内存
每一个线程有一个工作内存,它包含两部分,该线程的私有栈和对主存部分变量拷贝的寄存器(包括程序计数器PC和CPU工作的高速缓存区)。
多线程模型下,每个工作线程不能访问另一个工作线程中的变量,线程间变量传递是通过主线程来完成的。因此可能存在这种情况,线程1对变量a进行赋值了,还没来得及写入内存中,线程2不知道线程1已修改变量a的值,继续使用a原来的值,这样就会出现问题。
1.2 volatile
volatile是java的关键字,使用volatile修饰的变量会强制将修改的值立即写入主存,主存中的值更新会使工作线程中的副本值失效。
- 保证内存可见性:某个线程修改了volatitle修饰的变量值,其他线程能够及时知道。
- 禁止指令重排序:当程序执行到volatitle修饰的变量的读写操作时,可以保证之前的语句已执行完,也能确定后面的逻辑还未执行
- 不保证原子性:volatitle不保证变量的任何操作都是原子性的,比如i++
1.3 synchronized
synchronized依赖于JVM,保证了同一时刻只能有一个线程在作用对象的作用范围内进行操作。
- 内存可见性:线程在加锁时,先清空工作内存->在主存中拷贝最新变量副本到工作线程->执行完代码->将更改后的共享变量刷到主存中->释放互斥锁
- 操作的原子性:因为synchronized保证了同一时间只有一个线程对代码块进行操作,所以操作是原子性的。
- 有序性:第一条的特性决定,在多线程环境中,代码执行是有序的。
1.4 volatile和synchronized的区别
- volatile不会加锁,比synchronized更轻量级,不会阻塞线程
- volatile标记的变量不会被编译器优化而synchronized可以(比如编译器重排优化)
- volatile是变量修饰符,而synchronized可以修改方法、变量、代码块、
- volatile不保证原子性,synchronized可以保证原子性
- 他们都能保证内存可见性
2. final,finally,finalize区别
2.1 final
final是个修饰词,可以修饰类,方法和属性
-
修饰类
final修饰的类不能被继承。
-
修饰方法
主要由两个原因
- 防止被继承,修改
- 早期java版本中性能优化
-
修饰属性
使用final修饰的属性,一旦初始化后就不能修改 ,可以理解该属性只能读不能改。
2.2 finally
finally做为异常处理的一部分,只能用在try/catch语句中,如果try语句被执行那么finally语句也肯定被执行(除非把进程杀掉了等异常情况)。
2.3 finalize
finalize()方法是在Object里定义的,在对象被回收时调用。一般情况下不需要手动去实现该方法。
如果非要调用,得调用其super方法。
2.4 final,finally,finalize区别
其实他们没有半毛钱关系,只是长得像