Java 中的 ThreadLocal

Posted 呼呼睡觉睡觉啦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 中的 ThreadLocal相关的知识,希望对你有一定的参考价值。

  1. 实现线程范围的共享变量。

  1. JDK提供了ThreadLocal在一个线程内传递同一个对象

  1. 方法调用一定是同一个线程执行的

  1. ThreadLocal一定要在finally中清除:因为当前线程执行完后有可能重新放入线程池中

  1. 可以把TheadLocal看成是全局Map<Thread,Object>:

    (1)每个线程获取ThradLocal变量时,使用Thread自身作为Key

    (2)ThreadLocal表示线程的“局部变量”,它确保每个线程的ThradLocal变量都是独立的

    (3)ThreadLocal适合在一个线程的处理流程中保持上下文(避免同一参数在所有方法中传递)

    (4)使用ThreadLocal要用try catch finally结构

package com.xuefei.util;

public class ThreadLocalTest {

    //创建一个ThreadLocal对象
    static ThreadLocal<String> threadLocal = new ThreadLocal<String>();

    public static void main(String[] args) {
        //通过set方法给当前线程绑定一个指定的值
        threadLocal.set("Bob");
        //通过get方法随时获取到绑定的值
        String current = threadLocal.get();
        String current2 = threadLocal.get();
        System.out.println(current);
        System.out.println(current2);
        //最后通过remove将变量从当前线程解除
        threadLocal.remove();

    }
}

咱们来看个例子:看一下线程中对象的传递

package com.xuefei.util;

public class User {
    //用户名
    String name;
    //用户级别
    int level;
    //构造方法注入
    public User(String name, int level) {
        this.name = name;
        this.level = level;
    }
}

class UserContext implements AutoCloseable {
    //定义全局唯一变量
    static final ThreadLocal<User> context = new ThreadLocal<User>();

    //获取当前线程的ThreadLocal.User;
    public static User getCurrentUser() {
        return context.get();
    }

    //初始化ThreadLocal的User
    public UserContext(User user) {
        context.set(user);
    }

    //移除ThreadLocal关联的User
    public void close() throws Exception {
        context.remove();
    }
}

class ProcessThread extends Thread {
    //声明Us对象类型
    User user;
    //构造方法注入User
    public ProcessThread(User user) {
        this.user = user;
    }

    public void run() {
        //线程注入user
        try (UserContext ctx = new UserContext(user)) {
            //调用方法
            new Greeting().hello();
            Level.checkLevel();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Greeting {
    void hello() {
        //获取当前线程对象
        User user = UserContext.getCurrentUser();
        System.out.println("Hello, " + user.name+"!");
    }
}
class Level {
    static void checkLevel() {
        //获取当前线程对象
        User user = UserContext.getCurrentUser();
        if(user.level > 100) {
            System.out.println(user.name + "is a VIP user");
        }
    }
}
package com.xuefei.util;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new ProcessThread(new User("Bob",120));
        Thread t2 = new ProcessThread(new User("Alice",98));
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Main end");
    }
}

运行结果

以上是关于Java 中的 ThreadLocal的主要内容,如果未能解决你的问题,请参考以下文章

14Java并发性和多线程-Java ThreadLocal

ThreadLocal

[Java并发包学习七]解密ThreadLocal

谈谈Java引用和Threadlocal的那些事

java 中的 ThreadLocal

java中的引用与ThreadLocal