`

ThreadLocal 多线程访问同一变量解决方案

 
阅读更多
声明:是参考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编程中的重要概念,它允许...理解并掌握Java多线程下变量共享的原理和解决方案,有助于编写出高效、稳定的并发程序。在实际开发中,应结合具体业务场景选择合适的同步机制,以达到最佳性能和安全性。

    Java多线程并发访问解决方案

    本文将深入探讨Java中的多线程并发访问解决方案,主要围绕以下几个核心知识点进行阐述: 1. **线程同步机制**: - **synchronized关键字**:Java中的synchronized提供了一种内置锁机制,它可以保证同一时间只有一...

    ThreadLocal

    ThreadLocal是Java编程语言中的一个类,用于在多线程环境中提供线程局部变量。它是一种特殊类型的变量,每个线程都有自己的副本,互不影响,从而实现线程间数据隔离。ThreadLocal通常被用来解决线程共享数据时可能...

    Java ThreadLocal 线程安全问题解决方案

    Java中的ThreadLocal是解决线程安全问题的一个重要工具,它提供了一种在多线程环境下为每个线程维护独立变量副本的方法,从而避免了共享状态带来的竞态条件和线程安全问题。 线程安全问题通常由全局变量和静态变量...

    正确理解ThreadLocal.pdf

    `ThreadLocal`是Java平台提供的一种线程局部变量的解决方案,它为每一个使用该变量的线程都提供了独立的变量副本,使得每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。这不同于普通的静态...

    Hystrix跨线程传递数据解决方案:HystrixRequestContext.docx

    ### Hystrix跨线程传递数据解决方案:HystrixRequestContext #### 前言 在分布式系统中,为了提高系统的稳定性和响应性,通常会采用微服务架构,并且使用断路器模式来隔离不同服务之间的故障传播。Netflix 的 ...

    Synchronized与ThreadLocal

    **ThreadLocal** 提供了一种线程本地存储的解决方案,为每个线程创建独立的副本,避免了线程间的共享和争用问题。 - **作用原理:** - ThreadLocal 维护了一个 Map 结构,其中 Key 是 ThreadLocal 对象本身,Value...

    1工作临时-servlet 多线程问题

    标题 "1工作临时-servlet 多线程问题" 暗示了我们在讨论Servlet在处理多线程环境下的挑战和解决方案。Servlet是Java Web开发中用于处理HTTP请求的服务端组件,常常需要处理并发请求,因此多线程是其核心特性之一。 ...

    DAO多线程的技巧.rar_dao

    - **分布式事务**:在分布式系统中,可能需要处理跨数据库的事务,这时可以采用两阶段提交(2PC)、补偿事务(TCC)或基于Saga的分布式事务解决方案。 5. **异步处理** - **Future和Callable**:使用Future和...

    JDK5中的多线程并发库.doc

    - **解决方案**:可以使用自定义`Map`,Key为`Thread`类型,Value为共享数据,或者利用`ThreadLocal`,每个线程都有自己独立的副本,通过`set()`和`get()`操作。 在实际应用中,开发者可以结合这些特性来设计复杂...

    Java多线程 - (一) 最简单的线程安全问题

    一个方法或变量被称为线程安全,当它在多线程环境下被调用时,仍然能保证其正确性和完整性。线程不安全则可能引发竞态条件(race condition),即多个线程同时访问和修改同一份数据,导致结果不可预测。 在Java中,...

    SimpleDateFormat线程不安全的5种解决方案.docx

    nable() { @Override public void run() { // 定义局部变量 SimpleDateFormat SimpleDateFormat simpleDateFormat = new ...根据实际应用场景,可以选择适合的解决方案以确保线程安全并提高程序的并发性能。

    mycat多租户解决方案二

    综上所述,Mycat的多租户解决方案通过`ThreadLocal`变量、SQL拦截和数据库驱动的改造,实现了对SAAS应用的数据隔离,同时保持了良好的性能和可扩展性。这一方案对于需要支持多个独立客户在同一应用下运行的场景具有...

    某电信项目多线程同步数据实例

    Java提供了丰富的API来支持多线程操作,例如Thread类、ExecutorService、Future、Callable、Semaphore等,这些工具帮助开发者管理线程的生命周期,控制并发执行,以及解决线程间的同步问题。 1. **线程创建**:在...

    Java中的线程同步与ThreadLocal无锁化线程封闭实现

    Java中的线程同步是多线程编程中必不可少的概念,它用于控制多个线程对共享资源的访问,确保数据的一致性和完整性。Synchronized关键字是Java提供的一个内置锁机制,用于实现线程同步。当synchronized修饰一个方法或...

    JDK5中的多线程并发库

    - **解决方案**:可以使用自定义`Map`以`Thread`对象为Key保存数据,或者使用`ThreadLocal`,它为每个线程维护独立的变量副本,确保线程安全。 6. **原子类型**: - **原子类型**:JDK5引入`java.util.concurrent...

    ASP.NET多线程编程(一)

    ASP.NET多线程编程是构建高性能、高并发Web应用程序的关键技术之一。在ASP.NET中,多线程可以用于实现后台任务、异步处理、并行计算等...在实际项目中,应结合具体场景灵活运用多线程技术,实现高效且可靠的解决方案。

Global site tag (gtag.js) - Google Analytics