39.md 3.9 KB
Newer Older
W
wizardforcel 已提交
1
# Java `ThreadLocal`示例
W
init  
wizardforcel 已提交
2 3 4 5 6 7 8 9 10

> 原文: [https://javatutorial.net/threadlocal-java-example](https://javatutorial.net/threadlocal-java-example)

ThreadLocal 是提供线程局部变量的类,用于实现线程安全。 存储的数据只能由特定线程访问。

![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)

ThreadLocal 扩展了 Object 类,并提供了线程限制,它是局部变量的“一部分”。

W
wizardforcel 已提交
11
## **创建`ThreadLocal`变量**
W
init  
wizardforcel 已提交
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

```java
ThreadLocal threadLocalExample = new ThreadLocal();
```

上面代码中 ThreadLocal 对象的实例化仅需要针对每个线程进行。

就像大多数类一样,一旦有了 ThreadLocal 的实例,就可以在其上调用方法。 一些方法是:

1.  get():返回此线程局部变量的当前线程副本中的值
2.  initialValue():返回当前线程局部变量的当前线程初始值
3.  remove():从当前线程中删除当前线程局部变量的值
4.  set(T value):将当前线程局部变量的当前线程副本设置为指定值

有关这些方法的更多详细信息,请访问原始 [Oracle 文档。](https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html)

ThreadLocal 实例是希望将状态与线程相关联的类中的私有静态字段(在大多数情况下)

## **实现示例**

```java
public class ThreadLocalExample { 
    public static class Example implements Runnable {
        private ThreadLocal<String> example = new ThreadLocal<String>();
        // override the run() method that comes from implementing Runnable class
        @Override
        public void run() {
            try {
                System.out.println("Getting values...");
                Thread.sleep(2000);
            }
            catch (InterruptedException e) {  
                System.out.println(e);
            }  
            example.set("Just a random text that will be displayed before the remove function");
            System.out.println("Before remove: " + example.get());
            example.remove();
            System.out.println("After remove: " + example.get());
        }
    }
    public static void main(String[] args) { 
        /* EXAMPLE THAT DOES NOT HAVE TO DO ANYTHING WITH THE STATIC CLASS ABOVE main*/
        ThreadLocal<String> local = new ThreadLocal<String>(); 
        local.set("First"); 
        System.out.println("Value: " + local.get()); 

        local.set("Second"); 
        System.out.println("Value: " + local.get()); 

        local.remove(); 
        System.out.println("Value: " + local.get());
        /* NEW EXAMPLE THAT USES THE STATIC CLASS DECLARED ABOVE main */
        Example runnable = new Example();
        Thread thread = new Thread(runnable);
        thread.start();
    } 
}
```

**输出**

```java
Value: First
Value: Second
Value: null
Getting values...
Before remove: Just a random text that will be displayed before the remove function
After remove: null
```

W
wizardforcel 已提交
82
## **分解**
W
init  
wizardforcel 已提交
83 84

上面的代码显示了两种使它起作用的方法:一种是通过拥有 Runnable 对象并将其传递给 Thread 实例,然后覆盖 run()方法,或者您可以简单地创建一个 ThreadLocal 实例并为其设置值,然后 可以获取或删除它。 从上面的示例中可以看到,即使它是相同的变量(局部变量),也可以包含不同的值。 在第一种情况下,它包含值“ First”。 在第二种情况下,它包含值“ Second”。 对于其他实现,我只显示了一个线程。 但是,每个线程都是独立的–意味着,如果您要创建另一个 Thread 实例(例如 thread2),并对其进行 start(),它将独立运行,并且与其他 Thread 实例变量无关。 要进行检查,可以在静态类中创建一个 ThreadLocal 实例,然后在重写的 run()方法中创建一个随机数,然后使用 set()方法将其传递给当前线程。 您将看到,如果您在两个或多个不同的线程上调用它,则它们都将具有不同的值。