直接聊技术!
描述
ThreadLocal直译为 本地线程,但是实际意思却不是这样的,它是一个容器,用于存放本地线程的局部变量,到底为什么叫ThreadLocal,讲道理,我也不知道!
业务描述
在一个类中调用三个线程,三个线程分别进行报数1、2、3
/**
* [@author](https://my.oschina.net/arthor):稀饭
* [@time](https://my.oschina.net/u/126678):下午8:10:59
* @filename:Sequence.java
*/
package demo;
public interface Sequence {
public int getNumber();
}
/**
* [@author](https://my.oschina.net/arthor):稀饭
* [@time](https://my.oschina.net/u/126678):下午8:12:24
* @filename:ClientThread.java
*/
package demo;
public class ClientThread extends Thread {
private Sequence sequence;
public ClientThread(Sequence sequence) {
// TODO Auto-generated constructor stub
this.sequence = sequence;
}
/**
* @Title: run
* @Description: TODO
*/
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " ==> " + sequence.getNumber());
}
}
}
/**
* @author:稀饭
* @time:下午8:18:27
* @filename:TestA.java
*/
package demo;
public class TestA implements Sequence {
private static int number = 0;
@Override
public int getNumber() {
// TODO Auto-generated method stub
number = number + 1;
return number;
}
public static void main(String[] args) {
Sequence sequence = new TestA();
ClientThread clientThread1 = new ClientThread(sequence);
ClientThread clientThread2 = new ClientThread(sequence);
ClientThread clientThread3 = new ClientThread(sequence);
clientThread1.start();
clientThread2.start();
clientThread3.start();
}
}
运行结果如下:
Thread-0 ==> 1
Thread-2 ==> 3
Thread-1 ==> 2
Thread-2 ==> 5
Thread-0 ==> 4
Thread-2 ==> 7
Thread-1 ==> 6
Thread-0 ==> 8
Thread-1 ==> 9
**源码分析:**Thread没有按照先后顺序输出,这个可以理解,毕竟线程的启动是随机的,而为什么输出的结果不是1、2、3、1、2、3、1、2、3呢,仔细分析才发现,number是static的,是类所共享的,无法保证对不同线程来说是安全的,大家操作的都是同一个变量,当然一直在递增了。
那么如何做到各自线程递增这样的结果呢?
现在引入ThreadLocal,源码如下
/**
* @author:稀饭
* @time:下午8:18:27
* @filename:TestA.java
*/
package demo;
public class TestB implements Sequence {
private static ThreadLocal<Integer> container = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
// TODO Auto-generated method stub
return 0;
}
};
@Override
public int getNumber() {
// TODO Auto-generated method stub
container.set(container.get() + 1);
return container.get();
}
public static void main(String[] args) {
Sequence sequence = new TestB();
ClientThread clientThread1 = new ClientThread(sequence);
ClientThread clientThread2 = new ClientThread(sequence);
ClientThread clientThread3 = new ClientThread(sequence);
clientThread1.start();
clientThread2.start();
clientThread3.start();
}
}
运行结果如下:
Thread-0 ==> 1
Thread-1 ==> 1
Thread-2 ==> 1
Thread-1 ==> 2
Thread-0 ==> 2
Thread-1 ==> 3
Thread-2 ==> 2
Thread-0 ==> 3
Thread-2 ==> 3
源码解析:在TestA中引入ThreadLocal之后输出的结果变成了我上面说的那样,用了ThreadLocal之后每个线程独立了,虽然同样是static,但是线程独立了,也就是说ThreadLocal会为每一个不同的线程设置一个独立的副本。
现在才是最重要的地方,我们自己来实现一个ThreadLocal
先来分析一下ThreadLocal的api:
public void set(T vlue) 将值放入线程局部变量中
public T get() 从线程局部变量中获取
public void remove() 从线程局部中移除值
protected T initialValue() 返回线程局部变量中的初始值
以下是我自己实现的ThreadLocal
/**
* @author:稀饭
* @time:上午10:36:34
* @filename:ThreadLocalContainer.java
*/
package demo;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class ThreadLocalContainer<T> {
private T value;
//这里使用了同步Map
private Map<String, T> map = Collections.synchronizedMap(new HashMap<String, T>());
// 将值放入线程局部变量中
public void set(T vlue) {
map.put(Thread.currentThread().getName(), vlue);
}
// 从线程局部变量中获取
public T get() {
if (!map.containsKey(Thread.currentThread().getName())&&map.get(Thread.currentThread().getName()) == null) {
value = initialValue();
map.put(Thread.currentThread().getName(), value);
}
T v = map.get(Thread.currentThread().getName());
return v;
}
// 从线程局部中移除值
public void remove() {
if (map.containsKey(Thread.currentThread().getName())) {
map.remove(Thread.currentThread().getName());
}
}
// 返回线程局部变量中的初始值
protected T initialValue() {
return value;
}
}
**源码分析:**在源码中我使用了线程安全的Map也就是同步Map,目的是为了防止出现多线程出现的不安全问题。
**Note:发布的这些文章全都是自己边学边总结的,难免有纰漏,如果发现有不足的地方,希望可以指出来,一起学习咯,么么哒。
开源爱好者,相信开源的力量必将改变世界:
** osc : https://git.oschina.net/xi_fan
github: https://github.com/wiatingpub
转载于:https://my.oschina.net/u/2286602/blog/833941
分享到:
相关推荐
在Java多线程编程中,`ThreadLocal`是一个非常重要的工具类,它提供了一种在每个线程内部存储线程私有实例的方法。通常情况下,当多个线程共享某个变量时,可能会引发线程安全问题。而`ThreadLocal`则提供了另一种...
当Java事务与ThreadLocal结合使用时,可以在不同的线程中维护各自的事务状态,比如在Spring框架中,每个线程的ThreadLocal可以存储一个TransactionStatus对象,这样就可以在线程内部管理当前事务的状态,而不会影响...
Java中的ThreadLocal是一个非常重要的工具类,它在多线程编程中扮演着独特角色,尤其在处理线程间数据隔离和共享时。ThreadLocal不是线程本身,而是为每个线程提供一个独立的变量副本,使得每个线程都可以独立地改变...
Java中的ThreadLocal是一个非常重要的工具类,它在多线程编程中扮演着独特角色,用于为每个线程提供独立的变量副本。理解ThreadLocal的工作原理和使用方法对于编写高效、安全的多线程程序至关重要。 ### ...
Java中的`ThreadLocal`类是一个非常实用的工具,它提供了线程局部变量的功能。线程局部变量意味着每个线程都拥有自己独立的变量副本,互不干扰,这在多线程编程中尤其有用,可以避免数据共享带来的同步问题。下面...
在这个例子中,`ThreadLocalTest`类中的`threadLocal`变量为每个线程初始化一个随机值,并且`increament()`方法会增加当前线程的`ThreadLocal`变量的值。由于每个线程都有自己的副本,因此不会发生数据竞争。 总结...
从本质上说,ThreadLocal是一种存储机制,它可以在每个线程中存储一个变量的副本,这样每个线程都可以访问自己的变量副本,而不需要与其他线程共享同一个变量。这种机制可以解决多线程编程中的线程安全问题,并且...
**线程局部变量(ThreadLocal)是Java编程中一个非常重要的工具类,它在多线程环境下提供了线程安全的数据存储。ThreadLocal并不是一个变量,而是一个类,它为每个线程都创建了一个独立的变量副本,使得每个线程都...
ThreadLocal的实现原理可以总结为:每个线程都有一个自己的ThreadLocalMap,用于存放线程的本地变量;ThreadLocal的set、get、remove方法都是基于ThreadLocalMap的操作。 ThreadLocal的优点是可以解决多线程访问...
`ThreadLocal`在Java中是一个非常重要的工具类,它为每个线程提供了单独的变量副本,每个线程都可以独立地改变自己副本的值,而不会影响其他线程所对应的副本。`ThreadLocal`的全称是`java.lang.ThreadLocal`,它并...
ThreadLocal并不是一个线程对象,而是线程局部变量,即threadlocalvariable,它的主要作用是确保每个线程都有自己的变量实例,互不干扰。 ### 一、ThreadLocal工作原理 ThreadLocal通过内部的Map存储每个线程的...
java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多...
ThreadLocal是一个非常重要的Java并发工具类,它的核心概念在于为每一个线程提供了一个独立的变量副本,从而避免了线程之间的数据竞争问题。这使得每个线程在访问ThreadLocal变量时,实际上是在访问该变量的一个独立...
ThreadLocal是Java中用于线程局部变量的一个工具类,它的工作原理主要体现在如何在不同的线程之间隔离变量的副本,确保每个线程拥有自己的独立数据。这个设计模式在多线程编程中尤其有用,因为它避免了传统的同步...
Java中的ThreadLocal是一个非常有用的工具类,它提供了一种线程局部变量的机制。线程局部变量(ThreadLocal)的特点是每个线程都有其独立的副本,这些副本之间互不干扰,即使它们共享同一个ThreadLocal实例。这使得...
误区一:ThreadLocal是Java线程的一个实现 ThreadLocal并非Java线程的实现,它只是一个工具类,用于创建线程局部变量。ThreadLocal并不直接管理线程,而是为每个线程创建一个单独的变量副本。当线程使用ThreadLocal...
Java并发编程实践中,ThreadLocal变量是一个非常重要的工具,它在JDK1.2版本就已经引入。ThreadLocal不是代表一个线程实例,而是一种线程局部变量的机制,它为每个线程提供了一个独立的变量副本,各个线程可以独立地...
【ThreadLocal】是Java编程语言中用于处理线程局部变量的一个工具类,它提供了一种在多线程环境中实现线程安全的局部变量的方式。在Java的并发编程中,ThreadLocal是一个非常重要的概念,它可以帮助我们创建独立于...
Java线程编程中的ThreadLocal类是一个非常重要的工具,它在多线程环境下提供了一种线程局部变量的机制。ThreadLocal并非是简单的变量,而是一种能够确保每个线程都拥有独立副本的变量容器。理解ThreadLocal的工作...