好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java ThreadLocal的设计理念与作用

java中的threadlocal类允许我们创建只能被同一个线程读写的变量。因此,如果一段代码含有一个threadlocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的threadlocal变量。

如何创建threadlocal变量

以下代码展示了如何创建一个threadlocal变量:

?

1

private threadlocal mythreadlocal = new threadlocal();

我们可以看到,通过这段代码实例化了一个threadlocal对象。我们只需要实例化对象一次,并且也不需要知道它是被哪个线程实例化。虽然所有的线程都能访问到这个threadlocal实例,但是每个线程却只能访问到自己通过调用threadlocal的set()方法设置的值。即使是两个不同的线程在同一个threadlocal对象上设置了不同的值,他们仍然无法访问到对方的值。

如何访问threadlocal变量

一旦创建了一个threadlocal变量,你可以通过如下代码设置某个需要保存的值:

?

1

mythreadlocal.set("a thread local value]);

可以通过下面方法读取保存在threadlocal变量中的值:

?

1

string threadlocalvalue = (string) mythreadlocal.get();

get()方法返回一个object对象,set()对象需要传入一个object类型的参数。

为threadlocal指定泛型类型

我们可以创建一个指定泛型类型的threadlocal对象,这样我们就不需要每次对使用get()方法返回的值作强制类型转换了。下面展示了指定泛型类型的threadlocal例子:

?

1

private threadlocal mythreadlocal = new threadlocal<string>();

现在我们只能往threadlocal对象中存入string类型的值了。

并且我们从threadlocal中获取值的时候也不需要强制类型转换了。

如何初始化threadlocal变量的值

由于在threadlocal对象中设置的值只能被设置这个值的线程访问到,线程无法在threadlocal对象上使用set()方法保存一个初始值,并且这个初始值能被所有线程访问到。

但是我们可以通过创建一个threadlocal的子类并且重写initialvalue()方法,来为一个threadlocal对象指定一个初始值。就像下面代码展示的那样:

?

1

2

3

4

5

6

7

8

9

10

11

private threadlocal mythreadlocal = new threadlocal<string>() {

 

   @override

 

   protected string initialvalue() {

 

     return "this is the initial value" ;

 

   }

 

};

一个完整的threadlocal例子

下面是一个完整的可执行的threadlocal例子:

?

1

2

3

4

5

6

7

8

9

10

11

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

public class threadlocalexample {

 

   public static class myrunnable implements runnable {

 

 

     private threadlocal threadlocal = new threadlocal();

 

     @override

 

     public void run() {

 

       threadlocal.set(( int ) (math.random() * 100d));

 

       try {

 

       thread.sleep( 2000 );

 

       } catch (interruptedexception e) {

 

 

       }

 

       system.out.println(threadlocal.get());

 

     }

 

   }

 

 

   public static void main(string[] args) {

 

      myrunnable sharedrunnableinstance = new myrunnable();

 

      thread thread1 = new thread(sharedrunnableinstance);

 

      thread thread2 = new thread(sharedrunnableinstance);

 

      thread1.start();

 

      thread2.start();

 

   }

 

}

上面的例子创建了一个myrunnable实例,并将该实例作为参数传递给两个线程。两个线程分别执行run()方法,并且都在threadlocal实例上保存了不同的值。如果它们访问的不是threadlocal对象并且调用的set()方法被同步了,则第二个线程会覆盖掉第一个线程设置的值。但是,由于它们访问的是一个threadlocal对象,因此这两个线程都无法看到对方保存的值。也就是说,它们存取的是两个不同的值。

关于inheritablethreadlocal

inheritablethreadlocal类是threadlocal类的子类。threadlocal中每个线程拥有它自己的值,与threadlocal不同的是,inheritablethreadlocal允许一个线程以及该线程创建的所有子线程都可以访问它保存的值。

以上所述是小编给大家介绍的java threadlocal的设计理念与作用详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

原文链接:https://blog.csdn.net/u011860731/article/details/48733073

查看更多关于Java ThreadLocal的设计理念与作用的详细内容...

  阅读:16次