文中例子来自互联网,但已找不到原出处。
在java中,如果某个对象是非线程安全的共享资源,在多线程环境下,如果不加任何限制,对该资源的访问会存在冲突问题。针对这个问题,有以下几种解决方案:
1.加synchronized关键字,这种做法会限制并发访问,影响效率;
2.使用ThreadLocal维护共享资源(变量),为每个使用共享资源(变量)的线程提供独立的变量副本,从而避免冲突问题。
下面先来看一个例子
/**
*
*序列号产生类
*/
public class SequenceNumber {
//序列号变量
private int segNum=0;
//获取下一个序列值
public int getNextNum(){
return ++segNum;
}
}
/**
*
* 序列号产生线程
*/
public class TestClient extends Thread{
//序列号产生类对象
private SequenceNumber sn;
//构造函数
public TestClient(String name,SequenceNumber sn) {
super(name);
this.sn = sn;
}
public void run() {
for (int i = 0; i < 3; i++) {
//每个线程打出3个序列值
System.out.println(getName()+":sn--->" + sn.getNextNum());
}
}
}
/**
*
* 主方法类
*/
public class Main {
public static void main(String[] args) {
SequenceNumber sn = new SequenceNumber();
// 3个线程共享sn,各自产生序列号
TestClient t1 = new TestClient("A",sn);
TestClient t2 = new TestClient("B",sn);
TestClient t3 = new TestClient("C",sn);
t1.start();
t2.start();
t3.start();
}
}
运行主方法类,输出
A:sn--->1
A:sn--->2
A:sn--->3
B:sn--->4
B:sn--->5
B:sn--->6
C:sn--->7
C:sn--->8
C:sn--->9
下面修改一下SequenceNumber类的实现
/**
*
*序列号产生类
*/
public class SequenceNumber {
//序列号变量,通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值
private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {
public Integer initialValue() {
return 0;
}
};
//获取下一个序列值
public int getNextNum() {
seqNum.set(seqNum.get() + 1);
return seqNum.get();
}
}
运行主方法类,输出
A:sn--->1
A:sn--->2
A:sn--->3
C:sn--->1
B:sn--->1
B:sn--->2
B:sn--->3
C:sn--->2
C:sn--->3
可见,将SequenceNumber类的seqNum变量由int类型换成自定义的ThreadLocal<Integer>类型后,各个线程之间操作该共享对象的变量就互不影响了。
具体原因可以看下ThreadLocal的源代码。
分享到:
相关推荐
理解ThreadLocal 理解ThreadLocal 理解ThreadLocal 理解ThreadLocal
### 理解ThreadLocal原理 ThreadLocal内部通过一个ThreadLocalMap来存储每个线程的副本。这个Map的键是ThreadLocal实例,值是线程的局部变量。每个线程都有自己的ThreadLocalMap,存储在Thread类的成员变量中。 ##...
ThreadLocal 简单理解 ThreadLocal 是 Java 中的一个类,它提供了一个简单的方式来在每个线程中存储变量,并且能够确保这些变量之间不受影响。下面是对 ThreadLocal 的简单理解。 一、背景 最近有人问我 ...
Android 中 ThreadLocal 的深入理解 Android 中 ThreadLocal 的深入理解是指在 Android 开发中对 ThreadLocal 的深入理解和应用。ThreadLocal 是 Java 语言中的一种线程内部数据存储机制,通过它可以在指定的线程中...
### 正确理解ThreadLocal:深入解析其工作原理与应用场景 #### 一、ThreadLocal的基本概念 `ThreadLocal`是Java平台提供的一种线程局部变量的解决方案,它为每一个使用该变量的线程都提供了独立的变量副本,使得每...
在使用ThreadLocal时,理解其工作原理和限制是非常重要的。合理的使用能够帮助我们编写出更高效、更易于维护的多线程程序,但也要避免滥用,因为它可能会引入难以察觉的并发问题和内存管理问题。
ThreadLocal深度理解
**标题:“JDK的ThreadLocal理解(一)使用和测试”** **正文:** ThreadLocal是Java中的一个非常重要的线程安全工具类,它在多线程编程中扮演着独特的角色。通过创建ThreadLocal实例,我们可以为每个线程提供一个...
为了更直观地理解`ThreadLocal`的工作原理,我们可以创建一个简单的`SimpleThreadLocal`类。下面是一个基本的实现: ```java public class SimpleThreadLocal<T> { private Map, T> valueMap = new HashMap(); ...
本资料主要聚焦于两种设计模式以及Java中的ThreadLocal特性。 首先,我们来探讨单例模式。单例模式是一种确保一个类只有一个实例,并提供全局访问点的设计模式。在Java中,通常通过私有构造函数、静态工厂方法或...
1. 多线程:理解ThreadLocal的使用必须建立在对多线程的理解基础上,包括线程的创建、执行、同步机制等。 2. 并发编程:ThreadLocal是解决并发问题的一种策略,它提供了一种避免共享状态的方式,减少了锁的使用。 3....
at 中专门为每一个 web 应用...理解 `ThreadLocal` 的工作原理以及它如何与类加载器交互,是避免此类问题的关键。在实际开发中,应当养成良好的编程习惯,如使用后及时清理 `ThreadLocal` 变量,以防止内存资源的浪费。
ThreadLocal是Java中用于线程局部变量的一个工具类,它允许在多线程环境下为每个线程创建独立的变量副本,从而避免了线程之间的数据...理解ThreadLocal的工作原理和使用方法,对于编写高效、安全的并发程序至关重要。
Java事务和ThreadLocal是两种在Java编程中至关重要的概念,它们分别用于处理多线程环境下的数据一致性问题和提供线程局部变量。 首先,我们来深入理解Java事务。在数据库操作中,事务是一系列操作的集合,这些操作...
然而,ThreadLocal在理解和使用过程中容易产生一些误区,这里我们将详细探讨这些常见的误解。 误区一:ThreadLocal是Java线程的一个实现 ThreadLocal并非Java线程的实现,它只是一个工具类,用于创建线程局部变量。...
Java中的ThreadLocal是一个非常重要的工具类,它在多线程编程中扮演着独特角色,尤其在处理线程间数据隔离和共享时。...通过查看这些示例,你可以更深入地理解ThreadLocal的工作方式以及如何在你的代码中有效地利用它。