java并发学习--第七章 JDK提供的线程工具类

一、ThreadLocal

  ThreadLocal类用于隔离多线程中使用的对象,为ThreadLocal类中传递的泛型就是要隔离的对象,简单的来说:如果我们在主线程创建了一个对象,并且需要给下面的多线程任务都传递这个对象,那么如果这个对象传递到ThreadLocal,那么每个线程获取的对象都是独立的,不会受其他线程的改变而改变。

  ThreadLocal中一共有三个常用方法:

  

  get()方法:获取与当前线程关联的ThreadLocal值。 

 

  set(T value)方法:设置与当前线程关联的ThreadLocal值。

  

  initialValue()方法:设置与当前线程关联的ThreadLocal初始值。

  

  我们来看一个列子,创建两个线程,两个线程共同使用一个对象,我们来观察这个对象的值以及ThreadLocal中这个对象的值:

  对象User类:

public class User {

    int num;

    public User(int num) {
        this.num = num;
    }

    /**
     * 我们只使用get方法,并且每次获取num都为其加1
     * 
     * 使用synchronized保证getNum获取的num是线程安全的
     * @return
     */
    synchronized public int getNum() {
        return num++;
    }

}

  线程任务类:

public class ThreadlocaDemo extends Thread{

    User user;

    ThreadlocaDemo(User user){
        this.user=user;
    }

    /**
     * 创建一个ThreadLocal对象,为它的泛型传入User
     */
    ThreadLocal<User> userLoacl = new ThreadLocal<User>(){
        /**
         * 初始化方法,将设置user中的初始值
         */
        @Override
        protected User initialValue() {
            User user=new User(10);
            return user;
        }
    };


    @Override
     public void run() {

        for (int i = 1; i <3 ; i++) {
            //休息一会儿
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //打印user中获取的值
            System.out.println(getName()+"user对象的值"+user.getNum());
            //打印ThreadLocal中的user对象的值
            System.out.println(getName()+"ThreadLocal中的user对象的值"+userLoacl.get().getNum());

        }

    }

}

  测试类:

public class Main {

    public static void main(String[] args) {
        //创建一个共用的对象
        User user=new User(10);
        //创建两个线程任务
        ThreadlocaDemo threadlocaDemo1=new ThreadlocaDemo(user);
        ThreadlocaDemo threadlocaDemo2=new ThreadlocaDemo(user);
        threadlocaDemo1.setName("这是1号线程:");
        threadlocaDemo2.setName("这是2号线程:");

        threadlocaDemo1.start();
        threadlocaDemo2.start();
    }
}

运行的结果:

 根据运行结果我们可以清楚的看到,在ThreadLocal中的user对象是隔离的,外面的user对象没有被隔离,被两个线程都进行修改过。

  

猜你喜欢

转载自www.cnblogs.com/daijiting/p/11585544.html