类的线程安全定义
如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的。
类的线程安全表现为:
- 操作的原子性
- 内存的可见性
不做正确的同步,在多个线程之间共享状态的时候,就会出现线程不安全。
怎么才能做到类的线程安全?
栈封闭
所有的变量都是在方法内部声明的,这些变量都处于栈封闭状态。
无状态
没有任何成员变量的类,就叫无状态的类
package com.caojiulu;
/**
*
*@author caojiulu
*
*类说明:无状态的类,没有任何的成员变量
*/
public class StatelessClass {
public int service(int a,int b) {
return a*b;
}
}
让类不可变
让状态不可变,两种方式:
1,加final关键字,对于一个类,所有的成员变量应该是私有的,同样的只要有可能,所有的成员变量应该加上final关键字,但是加上final,要注意如果成员变量又是一个对象时,这个对象所对应的类也要是不可变,才能保证整个类是不可变的。
示例代码:
package com.caojiulu;
/**
*@author caojiulu
*
*类说明:看起来不可变的类,实际是可变的
*/
public class ImmutableFinalRef {
private final int a;
private final int b;
private final User user;//这里,就不能保证线程安全啦
public ImmutableFinalRef(int a, int b) {
super();
this.a = a;
this.b = b;
this.user = new User(2);
}
public int getA() {
return a;
}
public int getB() {
return b;
}
public User getUser() {
return user;
}
public static class User{
private int age;
public User(int age) {
super();
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public static void main(String[] args) {
ImmutableFinalRef ref = new ImmutableFinalRef(12,23);
User u = ref.getUser();
u.setAge(35);
}
}
2、根本就不提供任何可供修改成员变量的地方,同时成员变量也不作为方法的返回值
volatile
保证类的可见性,最适合一个线程写,多个线程读的情景,
加锁和CAS
安全的发布
类中持有的成员变量,特别是对象的引用,如果这个成员对象不是线程安全的,通过get等方法发布出去,会造成这个成员对象本身持有的数据在多线程下不正确的修改,从而造成整个类线程不安全的问题。
package com.caojiulu;
import java.util.ArrayList;
import java.util.List;
/**
*@author caojiulu
*
*类说明:存在着不安全的发布
*/
public class UnsafePublish {
//要么用线程的容器替换
//要么发布出去的时候,提供副本,深度拷贝
private List<Integer> list = new ArrayList<>(3);
public UnsafePublish() {
list.add(1);
list.add(2);
list.add(3);
}
//讲list不安全的发布出去了
public List<Integer> getList() {
return list;
}
//也是安全的,加了锁--------------------------------
public synchronized int getList(int index) {
return list.get(index);
}
public synchronized void set(int index,int val) {
list.set(index,val);
}
}
TheadLocal
ThreadLocal的实例代表了一个线程局部的变量,每条线程都只能看到自己的值,并不会意识到其它的线程中也存在该变量。
它采用采用空间来换取时间的方式,解决多线程中相同变量的访问冲突问题。
标签:java,变量,int,age,编程,list,并发,线程,public From: https://blog.51cto.com/u_14906615/5899411