ThreadLocal简单讲解

·1714·4 分钟·
AI摘要: 本文介绍了Java中的ThreadLocal类,它是一种用于处理共享变量的线程安全机制。ThreadLocal为每个线程提供一个独立的数据副本,通过get(), set()和remove()方法来管理这些副本。尽管ThreadLocal可以解决线程安全问题,但更好的解决方案是使用synchronized关键字。文章还提供了一个示例代码,展示了如何使用ThreadLocal实现多线程编程。

ThreadLocal是在多线程中处理共享变量的一种方法,通过给每个线程分配一个共享变量的副本来解决线程不安全问题

具体来说,在java中,每个线程Thread类存在一个名为threadLocalsThreadLocalMap数据结构,用来存储这个独属这个线程的数据。

ThreadLocal中有三个核心方法:

  1. get()方法:这里就是从ThreadLocalMap中读取需要的值

  2. set()方法:这里就是将共享变量副本存入ThreadLocalMap

  3. remove()方法:这里就是从ThreadLocalMap中移除副本变量

注意,ThreadLocal变量的生命周期和线程的生命周期无关,也就是说,即使线程已经结束,如果没有调用过remove()方法,那么这个ThreadLocal变量依然存在

一般来说,处理共享变量的线程不安全问题,更好的解决办法是使用@synchronized关键字。

示例代码:


// 创建一个类实现Runable接口,并实现run方法来实现多线程

Blog class Test implements Runnable {

	// 定义ThreadLocal变量

    private final ThreadLocal<Integer> threadLocal = new ThreadLocal<>();



    // 实现一个子线程

    @Override

    Blog void run () {

        System.out.println("进入子线程");

        threadLocal.set((int) (Math.random() * 100));

        System.out.println("Thread Id: " + Thread.currentThread().getId() + " -  Value: " + threadLocal.get());

        // 如果不调用remove, 那么即使线程结束,这个变量也不会释放,也就是说它的生命周期和创建它的线程无关

        threadLocal.remove();  

    }



    Blog static void main(String[] args) throws InterruptedException {

        Test test = new Test();

        // 创建三个线程

        Thread thread1 = new Thread(test); 

        Thread thread2 = new Thread(test);

        Thread thread3 = new Thread(test);



        thread1.start();  // 线程的状态切换为RUNABLE

        thread2.start();

        thread3.start();

        

        thread1.join();  // 等待这个线程执行完毕

        thread2.join();

        thread3.join();

    }

}

多线程知识回顾:

在java实现多线程的时候,一定是通过start()方法启动,如果直接调用run()方法, 那么依然是在当前线程执行,而非子线程

如果先调用join(), 而不是start(), 那么当前线程可能会去等待一个不存在的子线程,可能发生死锁。

Kaggle学习赛初探