声明:是参考stamen的文章写的,文章中很多地方也是摘抄于他的 《学习Spring必学的Java基础知识(6)----ThreadLocal》文章,http://www.iteye.com/topic/1123824
一提到多线程的话就会想到一个问题,就是对同一变量访问的安全性和准确性,要解决这个问题其实也有很多的方法,像加同步锁,创建一个线程外部能够访问到的map等等吧,而ThreadLocal无疑是最好的一种解决方案,它不会像同步一样降低并发性也不会像建立一个外部map那样书写过多的代码。
现在让我们认识下ThreadLocal,我主要的目的还是要学会用,而不是讲解ThreadLocal的来源什么的。首先ThreadLocal类为我们提供的对我方法有4个分别是:
- void set(Object value)
设置当前线程的线程局部变量的值;
- public Object get()
该方法返回当前线程所对应的线程局部变量;
- public void remove()
将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度;
- protected Object initialValue()
返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的默认实现直接返回一个null。
至于应用,看下下面一段代码就能够明白,很简单
package com.baobaotao.basic;
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();
}
public static void main(String[ ] args)
{
SequenceNumber sn = new SequenceNumber();
//③ 3个线程共享sn,各自产生序列号
TestClient t1 = new TestClient(sn);
TestClient t2 = new TestClient(sn);
TestClient t3 = new TestClient(sn);
t1.start();
t2.start();
t3.start();
}
private static class TestClient extends Thread
{
private SequenceNumber sn;
public TestClient(SequenceNumber sn) {
this.sn = sn;
}
public void run()
{
//④每个线程打出3个序列值
for (int i = 0; i < 3; i++) {
System.out.println("thread["+Thread.currentThread().getName()+
"] sn["+sn.getNextNum()+"]");
}
}
}
}
这里有个知识点要说下,就是这段代码:
private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){
public Integer initialValue(){
return 0;
}
};
这段代码其实是一个内部类,上面说过了initialValue()这个方法是为了子类重写的,这样的定义就是声明了一个匿名内部类,继承了ThreadLocal类并重写了initialValue()方法,因为这个子类是匿名的,你无法在后续的代码里引用,所以必须在定义时同时创建实例,他的作用就相当于这段代码。
class OutterClass {
private static class MyThreadLocal extends ThreadLocal<Integer> {
public Integer initialValue(){
return 0;
}
}
private static MyThreadLocal seqNum = new MyThreadLocal();
}
分享到:
相关推荐
然而,需要注意的是,线程局部变量并不是线程安全的解决方案。如果你需要在线程间共享数据,并确保数据的一致性,那么应该使用其他同步机制,如`synchronized`关键字、`java.util.concurrent`包中的原子类或`...
Java多线程是Java编程中的重要概念,它允许...理解并掌握Java多线程下变量共享的原理和解决方案,有助于编写出高效、稳定的并发程序。在实际开发中,应结合具体业务场景选择合适的同步机制,以达到最佳性能和安全性。
本文将深入探讨Java中的多线程并发访问解决方案,主要围绕以下几个核心知识点进行阐述: 1. **线程同步机制**: - **synchronized关键字**:Java中的synchronized提供了一种内置锁机制,它可以保证同一时间只有一...
ThreadLocal是Java编程语言中的一个类,用于在多线程环境中提供线程局部变量。它是一种特殊类型的变量,每个线程都有自己的副本,互不影响,从而实现线程间数据隔离。ThreadLocal通常被用来解决线程共享数据时可能...
Java中的ThreadLocal是解决线程安全问题的一个重要工具,它提供了一种在多线程环境下为每个线程维护独立变量副本的方法,从而避免了共享状态带来的竞态条件和线程安全问题。 线程安全问题通常由全局变量和静态变量...
`ThreadLocal`是Java平台提供的一种线程局部变量的解决方案,它为每一个使用该变量的线程都提供了独立的变量副本,使得每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。这不同于普通的静态...
### Hystrix跨线程传递数据解决方案:HystrixRequestContext #### 前言 在分布式系统中,为了提高系统的稳定性和响应性,通常会采用微服务架构,并且使用断路器模式来隔离不同服务之间的故障传播。Netflix 的 ...
**ThreadLocal** 提供了一种线程本地存储的解决方案,为每个线程创建独立的副本,避免了线程间的共享和争用问题。 - **作用原理:** - ThreadLocal 维护了一个 Map 结构,其中 Key 是 ThreadLocal 对象本身,Value...
标题 "1工作临时-servlet 多线程问题" 暗示了我们在讨论Servlet在处理多线程环境下的挑战和解决方案。Servlet是Java Web开发中用于处理HTTP请求的服务端组件,常常需要处理并发请求,因此多线程是其核心特性之一。 ...
- **分布式事务**:在分布式系统中,可能需要处理跨数据库的事务,这时可以采用两阶段提交(2PC)、补偿事务(TCC)或基于Saga的分布式事务解决方案。 5. **异步处理** - **Future和Callable**:使用Future和...
- **解决方案**:可以使用自定义`Map`,Key为`Thread`类型,Value为共享数据,或者利用`ThreadLocal`,每个线程都有自己独立的副本,通过`set()`和`get()`操作。 在实际应用中,开发者可以结合这些特性来设计复杂...
一个方法或变量被称为线程安全,当它在多线程环境下被调用时,仍然能保证其正确性和完整性。线程不安全则可能引发竞态条件(race condition),即多个线程同时访问和修改同一份数据,导致结果不可预测。 在Java中,...
nable() { @Override public void run() { // 定义局部变量 SimpleDateFormat SimpleDateFormat simpleDateFormat = new ...根据实际应用场景,可以选择适合的解决方案以确保线程安全并提高程序的并发性能。
综上所述,Mycat的多租户解决方案通过`ThreadLocal`变量、SQL拦截和数据库驱动的改造,实现了对SAAS应用的数据隔离,同时保持了良好的性能和可扩展性。这一方案对于需要支持多个独立客户在同一应用下运行的场景具有...
Java提供了丰富的API来支持多线程操作,例如Thread类、ExecutorService、Future、Callable、Semaphore等,这些工具帮助开发者管理线程的生命周期,控制并发执行,以及解决线程间的同步问题。 1. **线程创建**:在...
Java中的线程同步是多线程编程中必不可少的概念,它用于控制多个线程对共享资源的访问,确保数据的一致性和完整性。Synchronized关键字是Java提供的一个内置锁机制,用于实现线程同步。当synchronized修饰一个方法或...
- **解决方案**:可以使用自定义`Map`以`Thread`对象为Key保存数据,或者使用`ThreadLocal`,它为每个线程维护独立的变量副本,确保线程安全。 6. **原子类型**: - **原子类型**:JDK5引入`java.util.concurrent...
ASP.NET多线程编程是构建高性能、高并发Web应用程序的关键技术之一。在ASP.NET中,多线程可以用于实现后台任务、异步处理、并行计算等...在实际项目中,应结合具体场景灵活运用多线程技术,实现高效且可靠的解决方案。