final
final修饰的变量是不能够被改变的,但是对于不同数据类型是有不同含义的。
final修饰变量
final修饰基本数据类型的变量和引用类型的变量。
- 当final修饰的是一个基本数据类型时,这个数据的值在初始化后将不能被改变,赋值的方式有:
class Test {
// private final int a = 1; // 显式初始化
private final int a;
/*{
a = 1; // 代码块初始化
}*/
public Template() {
a = 1; // 构造方法初始化
}xianshi
// 修饰形参时:调用该方法时,一旦赋值形参,方法体内部不可更改其值。
public void ch(final int a) {
// 形参赋值不可更改其值
}
}- 当final修饰一个引用类型数据时,即修饰一个对象时,引用在初始化后永远指向一个内存地址,不可修改,但是该内存地址中保存的对象信息是可以进行修改的。- final修饰的常量在编译阶段会被放入常量池中。
- 局部、匿名内部类在使用外部局部变量时,只能使用被final修饰的变量。在java8之后,不用显式地声明局变量为final,java8之前,需要声明。
final修饰方法
- 锁定方法,被修饰的方法继承类不能进行修改。
- 在编译器对方法进行内联,提升效率,但是很少这么使用了。
final修饰类
被修饰的类不能被继承,被修饰的类所有的成员方法都将被隐式修饰为final方法。
synchronized
修饰方法
- 成员方法:实例方法并不是类所独有的,每个对象实例独立拥有它,它并不被对象实例所共享。这也比较能推出,在实例方法上加入synchronized,那么它获取的就是这个类的锁,锁住的就是这个对象实例。
- 静态方法:静态方法是属于“类”,不属于某个实例,是所有对象实例所共享的方法。也就是说如果在静态方法上加入synchronized,那么它获取的就是这个类的锁,锁住的就是这个类。
synchronized和Lock的区别
- synchronized是Java中的一个关键字,Lock是一个接口。
- synchronized是隐式锁,Lock是显式锁。
- synchronized会自动释放锁,Lock必须手动释放锁。
- Lock可以让等待锁的线程响应中断,而synchronized不会,线程会一直等待。
- Lock可以知道线程有没有拿到锁,而synchronized不能。
synchronized是非公平锁;lock可以是公平锁,也可以是非公平锁,默认是非公平锁,在其构造方法的时候可以传入Boolean值,true为公平锁,false为非公平锁。
- ps:非公平锁可以理解成可以插队
7.synchronized是悲观锁,Lock是乐观锁。 - 悲观锁:线程获得的是独占锁,独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。在cpu转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起cpu频繁的切换上下问导致效率很低。
- 乐观锁:每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁实现的机制时是CAS(Compare and Swap)操作。
- ps:非公平锁可以理解成可以插队