线程安全 1

课程素材来自 http://enjoy.ke.qq.com/    版权所有

什么是线程安全

如果多个线程访问并使用这个类,这类总是表现线程安全的,那么这个类就是线程安全的。

类的线程安全表现为:

l  操作的原子性

l  内存的可见性

不做正确的同步,在多个线程之间共享状态的时候,就会出现线程不安全。

怎么做到线程安全

栈封闭

所有的变量都在方法内部声明的,这些状态都处于栈封闭状态。

示例代码:



无状态的类

     没有任何成员变量的类,就叫无状态的类

package com.hw.ch9;
public class Stateless {
    public String  result() {
        return "success";
    }
}


让类不可变

让状态不可变,两种方式:

1,加final关键字,对于一个类,所有的成员变量应该是私有的,同样的只要有可能,所有的成员变量应该加上final关键字,

但是加上final,要注意如果成员变量又是一个对象时,这个对象所对应的类也要是不可变,才能保证整个类是不可变的。

public class ImmutableFinal {
    private  final  int a;
    private  final  int b;
    public  ImmutableFinal(int a, int b){
        this.a=a;
        this.b=b;
    }
    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }
}

2、根本就不提供任何可供修改成员变量的地方,同时成员变量也不作为方法的返回值

public class ImmutableFinalRef {
    private  final  int a;
    private  final  int b;
    private  final  User  user;
    public ImmutableFinalRef(int a, int b,User  user){
        this.a=a;
        this.b=b;
        this.user  = user;
    }
    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }

    public  static  class  User{
        private int  age;
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }
这样的也是不安全的操作,因为别个的线程可以获取到user对象的引用,可以改变user的值,但是,把
 
 
   user对象的代码改成这样  
    public    class  User{
//        private int  age;
        private  final int  age;
        public  User(int  age){
            this.age  = age;
        }
        public int getAge() {
            return age;
        }
//        public void setAge(int age) {
//            this.age = age;
//        }
    }
线程就安全了,因为没有修改的方法了。


volalite

保证类的可见性,最适合一个线程写,多个线程读的情景


加锁和cas

安全的发布

类中持有的成员变量,特别是对象的引用,如果这个成员对象不是线程安全的,
通过get等方法发布出去,会造成这个成员对象本身持有的数据在多线程下不正确的
修改,从而造成整个类线程不安全的问题。

ThreadLocal
 
 
 
 
多个线程变量安全

猜你喜欢

转载自blog.csdn.net/pf1234321/article/details/80469962
今日推荐