什么是不变性(Immutable)
如果对象在被创建后,状态就不能被修改,那么它就是不可变的。
具有不变性的对象一定是线程安全的,我们不需要对其采取任何额外的安全措施,也能保证线程安全。
代码演示
/**
* @Classname Person
* @Description 不可变对象,演示其他类无法修改这个对象。
* @Date 2021/2/18 17:12
* @Created by YoungLiu
*/
public class Person {
//加了final
final int age =18;
final String name ="Alice";
public static void main(String[] args) {
Person person = new Person();
//这里会报错,因为都是final修饰的,不可变。
person.age=19;
}
}
final关键字的作用
final修饰变量
被final修饰的变量,意味着值不能被修改。如果变量是对象,那么对象的引用不能变,但是对象自身的内容依然可以变化。
public class Person {
//加了final
final int age =18;
final String name ="Alice";
String bag ="this is the content of object.";
public static void main(String[] args) {
final Person person = new Person();
//这里会报错,因为被final的对象变量,对象的引用不能改变。
person = new Person();
//对象的内容可以改变
person.bag="The object content could be change.";
}
}
/**
* @Classname FinalVariableDemo
* @Description 演示final变量的赋值时机,final修饰的变量必须选择一种赋值时机
* @Date 2021/2/18 17:30
* @Created by YoungLiu
*/
public class FinalVariableDemo {
//第一种赋值时机
// private final int a =6;
private final int a ;
//第二种赋值时机
// public FinalVariableDemo(int a) {
// this.a = a;
// }
//第三种赋值情况
{
a= 6;
}
}
/**
* @Classname FinalVariableDemo2
* @Description 演示final static变量的赋值时机,
* @Date 2021/2/18 17:30
* @Created by YoungLiu
*/
public class FinalVariableDemo2 {
//第一种赋值时机
// private static final int a = 3 ;
private static final int a ;
//第二种赋值时机
static{
a= 6;
}
}
public class FinalVariableDemo2 {
void testFinal(){
//对于local final 变量 在使用前必须先赋值
final int b;
}
}
final修饰方法
/**
* @Classname FinalMethodDemo
* @Description 演示被final修饰的方法
* @Date 2021/2/18 20:00
* @Created by YoungLiu
*/
public class FinalMethodDemo {
public void drink(){
}
public final void eat(){
}
public static void sleep(){
}
}
class SubClass extends FinalMethodDemo{
@Override
public void drink() {
super.drink();
}
//不能重写父类的final 方法
// public void eat(){
//
// }
//不能重写父类的static方法,但可以写成一模一样。
// public static void sleep(){
//
// }
}
final修饰类
如果我们知道,某个类,方法,变量,定义后就不会改变了,那么我们可以使用final去修饰。
不变性和final的关系
扫描二维码关注公众号,回复:
12532819 查看本文章
栈封闭
代码演示
/**
* @Classname StackConfinement
* @Description 演示栈封闭的两种情况:基本变量和对象
* 1.先演示线程争抢带来错误结果,然后把变量放到方法内,情况就变了。
* @Date 2021/2/18 20:19
* @Created by YoungLiu
*/
public class StackConfinement implements Runnable{
//全局变量被两个线程共享,会出现线程安全的问题;
int index = 0;
public void inThread(){
//每个线程都有一个nerverGoOut变量
int neverGoOut = 0;
for(int i =0;i<10000;i++){
neverGoOut++;
}
System.out.println("栈内保护的数字是线程安全的:"+neverGoOut);
}
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
index++;
}
inThread();
}
public static void main(String[] args) throws InterruptedException {
StackConfinement r1 = new StackConfinement();
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r1);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(r1.index);
}
}
从程序输出的结果可知,全局变量是共享资源区。