您的位置:首页 > 编程语言 > Java开发

Java ThreadLocal使用浅析

2009-08-18 20:14 429 查看
Java ThreadLocal使用浅析


JAVA API

文档里关于
ThreadLocal

的定义是:

This
class provides thread-local variables. These variables differ from
their normal counterparts in that each thread that accesses one (via
its
get

or
set

method) has its own, independently initialized copy of the variable.

ThreadLocal

instances are typically private static fields in classes that wish to
associate state with a thread (e.g., a user ID or Transaction ID).

这个类提供了一个线程本地的变量。这些变量在被共享访问的情况下在不同的线程里是独立的
(
必须通过
get

set
方法来访问
)


很显然该类提供了一个机制可以防止多线程访问带来的不安全机制。实际上就是在线程本地保存一个变量,而不是通过共享变量。这个就要看我们的使用场合了,如果我们确实需要共享的数据,那还是必须通过同步机制来保证数据的安全。如果有些情况希望不同的线程保存的变量各自分开,那用这个还是比较合适的。

ThreadLocal

这个类本身不是代表线程要访问的变量,这个类的成员变量才是。
JDK1.5



ThreadLocal

加了泛型功能,即是
ThreadLocal<T>,

这个泛型
T

即是要线程的本地变量。线程通过
ThreadLocal


get


set

方法去访问这个变量
T


ThreadLocal

提供了一个机制,它能保证线程通过这个来访问它来访问类型为
T

的变量的时候是不同的拷贝。所以访问该变量必须通过
Threadlocal

这个类只提供了两个
public

方法,即是
get()


set

()方法来访问。

同时还提供了一个
inintValue()

protected
方法。该方法用来初始化变量值。

注意
:默认情况下

initValue(),

返回

null

。线程在没有调用

set

之前,第一次调用

get

的时候,

get

方法会默认去调用

initValue

这个方法。所以如果没有覆写这个方法,可能导致

get

返回的是

null

。当然如果调用过

set

就不会有这种情况了。但是往往在多线程情况下我们不能保证每个线程的在调用

get

之前都调用了

set

,所以最好对

initValue

进行覆写,以免导致空指针异常。

说了这么多,估计还不如看下例子吧,下面还是上例子。

例子

1

:没有使用

Threadlocal

的情况:

/**

*

*

@author

yblin

*

2009.8.18

*

*/

public

class

TestWithNoThreadLocal

{

public

static

int

a

=

0;

public

static

void

main(String[]

args)

{

MyThread

myThread

=

new

MyThread();

myThread.start();

for

(
int

i

=

0;

i

<

5;

i++)

{

a

=

a

+

1;

System.
out

.println(Thread.
currentThread

().getName()

+

":"

+

a

);

}

}

public

static

class

MyThread

extends

Thread

{

public

void

run()

{

for

(
int

i

=

0;

i

<

5;

i++)

{

a

=

a

+

1;

System.
out

.println(Thread.
currentThread

().getName()

+

":"

+

a

);

}

}

}

}

运行的一种结果如下:

main:2

Thread-0:2

main:3

Thread-0:4

main:5

Thread-0:6

main:7

Thread-0:8

main:9

Thread-0:10

在没有同步的机制下,该结果有不安全的情况发生是正常的,两个线程都得到

2

。下面请看用了

ThreadLocal

的效果。

例子

2

:使用了

Threadlocal

的情况:

/**

*

*

@author

yblin

*

2009.8.18

*

*/

public

class

TestThreadLocal2

{

private

static

ThreadLocal<Integer>

a

=

new

ThreadLocal<Integer>()

{

public

Integer

initialValue()

{
//

初始化,默认是返回

null

return

0;

}

};

public

static

void

main(String

args[])

{

MyThread

my;

my

=

new

MyThread();

my.start();

for

(
int

i

=

0;

i

<

5;

i++)

{

a

.set(
a

.get()

+

1);

System.
out

.println(Thread.
currentThread

().getName()

+

":"

+

a

.get());

}

}

public

static

class

MyThread

extends

Thread

{

public

void

run()

{

for

(
int

i

=

0;

i

<

5;

i++)

{

a

.set(
a

.get()

+

1);

System.
out

.println(Thread.
currentThread

().getName()

+

":"

+

a

.get());

}

}

}

}

运行的一种结果如下:

main:1

Thread-0:1

main:2

Thread-0:2

main:3

Thread-0:3

main:4

Thread-0:4

Thread-0:5

main:5

如上是关于

ThreadLocal

的简单介绍。其内部具体实现可看其类实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: