06-JUC--Immutable

什么是不变性(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);
    }
}

从程序输出的结果可知,全局变量是共享资源区。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41729287/article/details/113850041
JUC