当前位置: 移动技术网 > IT编程>开发语言>Java > 7.1 什么是线程安全的类,实现线程安全对象的常用方法总结

7.1 什么是线程安全的类,实现线程安全对象的常用方法总结

2020年07月12日  | 移动技术网IT编程  | 我要评论

目录

 

1、在《Java并发编程实战》中,定义如下:

2、实现线程安全的类常用方式

2.1线程封闭:把对象封装到线程中,只有这个线程能够看到此对象

2.2无状态的类:没有任何成员变量的类

2.3 让类不可变

2.3.1 加final关键字

2.3.2不提供修改成员变量,也不提供获取成员变量方法

2.4 volatile

2.5 加锁和CAS

2.6 安全的发布类:8个基本数据类型:int\short\char\byte\float\double\boolean\long

2.7 使用ThreadLocal

3 为什么servlet不是线程安全的类


1、在《Java并发编程实战》中,定义如下:

当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在调用代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。

2、实现线程安全的类常用方式

线程封闭 把对象封装到线程中,只有这个线程能够看到此对象
无状态的类 没有任何成员变量的类
让类不可变

1、加final关键字

2、不提供修改成员变量,也不提供获取成员变量方法

使用volatile 保证类的可见性,不能保证线程安全。适合一写多读的场景
加锁和CAS 使用synchronized、lock、原子变量AtomicInteger等
安全的发布

如果类中有基本类型成员变量,发布出去其实是变量的副本,不是引用

int、short、char、byte、float、double、boolean、long

ThreadLocal 每个线程自己维护了一个ThreadLocalMap

2.1线程封闭:把对象封装到线程中,只有这个线程能够看到此对象

2.2无状态的类:没有任何成员变量的类

/**
 * 无状态的类:没有任何变量
 */
public class Test{
	public int add(int a,int b){

	    return a+b;
    }

    public void test(UserVo user){

    }
}

2.3 让类不可变

2.3.1 加final关键字

/**
 * 类变量不能被修改,只能获取
 **/
public class Test1 {
     private final String name;
     private final Integer age;

    public Test1(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }
}

2.3.2不提供修改成员变量,也不提供获取成员变量方法

/**
 * 没有获取值、修改值的方法,所以是线程安全的
 **/
public class Test2 {
    private Integer[] a = new Integer[]{1,2,3};
    
    public boolean testContain(int b){
        return Arrays.asList(a).contains(b);
    }
}

2.4 volatile

2.5 加锁和CAS

使用synchronized、lock、原子变量AtomicInteger等

2.6 安全的发布类:8个基本数据类型:int\short\char\byte\float\double\boolean\long

/**
 * 基本数据类型,在每个线程中会是一个副本
 **/
public class Test3 {
    private int a;
    private boolean b;
    private byte c;
    private float d;
    private double e;
    private short f;
    private char g;
    private long h;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public static void main(String[] args) {
        Test3 test3 = new Test3();
        test3.setA(1);
        System.out.println(test3.getA());
    }
}

2.7 使用ThreadLocal

3 为什么servlet不是线程安全的类

servlet不是线程安全的类,我们平时用却没有考虑多线程?

1、很少有需要共享servlet的需求

2、从接受请求到返回应答,基本都是由一个线程来完成的

但是还是要警惕,如果servlet中有成员变量,不做好控制,很可能会发生线程安全问题

 

本文地址:https://blog.csdn.net/qq_22701869/article/details/107271921

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网