`
hotsheqaz
  • 浏览: 19682 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
  • hi_gp: hotsheqaz 写道hi_gp 写道为啥我按照你的示例,在 ...
    XML约束
  • hotsheqaz: hi_gp 写道为啥我按照你的示例,在book.xml中加上定 ...
    XML约束
  • hi_gp: 为啥我按照你的示例,在book.xml中加上定义的book.d ...
    XML约束

ThreadLocal实现线程范围的共享变量

 
阅读更多

 

package com.itcast;

import java.util.Random;

public class ThreadScopeShareMoney {

	/**
	 * @param args
	 */
	private static int money = 0;
	private static ThreadLocal<Integer> threadlocal = new ThreadLocal<Integer>();   // ThreadLocal线程局部变量
	public static void main(String[] args) {
		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					int money = new Random().nextInt();
					System.out.println(Thread.currentThread().getName()
							+ " put money: " + money);
					threadlocal.set(money);
					MyThreadScopeData.getThreadInstance().setName("name" + money);  //  在线程当中添加数据
					MyThreadScopeData.getThreadInstance().setMoney(money);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}

	static class A {
		public void get(){
			int data = threadlocal.get();	//从当前的线程取出数据		
			System.out.println("A from " + Thread.currentThread().getName() 
					+ " get data :" + data);
			MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
			System.out.println("A from " + Thread.currentThread().getName() 
					+ " getData: " + myData.getName() + "," +
					myData.getMoney());			
		}		
	}

	static class B{
		public void get(){
			int data = threadlocal.get();	//从当前的线程取出数据			
			System.out.println("B from " + Thread.currentThread().getName() 
					+ " get data :" + data);
			MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
			System.out.println("B from " + Thread.currentThread().getName() 
					+ " getMyData: " + myData.getName() + "," +
					myData.getMoney());			
		}		
	}
}

class MyThreadScopeData {
	private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
	
	private MyThreadScopeData(){
		
	}
	public static MyThreadScopeData getThreadInstance(){       //懒汉模式
		MyThreadScopeData instance = map.get();
		if(instance==null){
			instance = new MyThreadScopeData();
			map.set(instance);
		}
		return instance;
	}
	private String name;
	private int money;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getMoney() {
		return money;
	}

	public void setMoney(int money) {
		this.money = money;
	}

}

 

运行结果为:
Thread-0 put money: -1153260093
Thread-1 put money: 264490866
A from Thread-0 get data :-1153260093
A from Thread-1 get data :264490866
A from Thread-0 getData: name-1153260093,-1153260093
A from Thread-1 getData: name264490866,264490866
B from Thread-1 get data :264490866
B from Thread-0 get data :-1153260093
B from Thread-1 getMyData: name264490866,264490866
B from Thread-0 getMyData: name-1153260093,-1153260093
 

实验步骤:
1.先在MyThreadLocalData类中定义一个访问权限为public的ThreadLocal类型的变量x,直接对这个x进行读写操作;
2.将变量x的访问权限定义为private, MyThreadLocalData上定义相应的set和get方法对向变量x中存储和检索数据;
3.将MyThreadLocalData类自身变成一个具有业务功能的对象,每个线程仅能有该类的一个实例对象,即对于不同的线程来说,MyThreadLocalData.getMyData静态方法拿到的对象都不相同,但对于同一个线程来说,不管调用MyThreadLocalData.getMyData多少次和在哪里调用,拿到的都是同一个MyThreadLocalData对象。MyThreadLocalData封装成具有业务功能的对象,然后设计getMyData方法的定义,最后定义getMyData方法要操作的ThreadLocal变量和编写具体的代码。

 

 

     ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据。每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加一条记录,key分别是各自的线程,value是各自的set方法传进去的值。在线程结束时可以调用ThreadLocal.clear()方法,这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量。

      总结:一个ThreadLocal代表一个变量,故其中里只能放一个数据,你有两个变量都要线程范围内共享,则要定义两个ThreadLocal对象。如果有一个百个变量要线程共享呢?那请先定义一个对象来装这一百个变量,然后在ThreadLocal中存储这一个对象。

 

分享到:
评论

相关推荐

    Java多线程编程之ThreadLocal线程范围内的共享变量

    总结来说,ThreadLocal是Java中用于多线程编程的一种重要工具,它通过为每个线程提供独立的变量副本,解决了共享变量带来的问题,同时在特定场景下提供了高效的数据管理和事务一致性。了解并合理利用ThreadLocal,能...

    Hibernate用ThreadLocal模式(线程局部变量模式)管理Session

    Session由SessionFactory创建,而SessionFactory是线程安全的,这意味着它可以被多个并发线程共享。然而,Session本身并不具备线程安全特性,也就是说,如果多个线程共用同一个Session实例,可能会引发数据混乱,...

    18 线程作用域内共享变量—深入解析ThreadLocal.pdf

    【线程作用域内共享变量】 在Java并发编程中,线程安全是一个重要的主题。传统的解决方案包括使用`Atomic`类、`volatile`关键字以及`synchronized`关键字来保证多线程环境下的数据一致性。然而,这些同步机制并不...

    多线程线程变量赋值

    当多个线程共享同一资源时,数据同步和安全问题就会变得至关重要。本话题聚焦于“多线程线程变量赋值”,讨论如何在不通过参数传递的情况下,为线程变量直接赋值。 首先,我们需要理解线程变量(Thread Local ...

    ThreadLocal 线程本地变量 及 源码分析.rar_开发_设计

    - 不要将ThreadLocal用作全局变量,因为它们只在创建它们的线程内有效,无法跨线程共享。 - 谨慎处理生命周期管理,尤其是在静态变量中使用ThreadLocal,确保在不再需要时正确清理,防止内存泄漏。 6. **应用场景...

    java多线程_java多线程下变量共享_

    在Java中,线程共享变量可以通过两种方式实现:静态成员变量和实例成员变量。静态成员属于类,所有该类的实例都可以访问,因此在多线程环境下默认共享;实例成员变量则属于对象,每个线程都有自己独立的副本,除非...

    Java并发编程学习之ThreadLocal源码详析

    ThreadLocal是Java并发编程中的一种机制,用于解决多线程访问共享变量的问题。它可以使每个线程对共享变量的访问都是线程安全的,使得多线程编程变得更加简单。 ThreadLocal的实现原理是基于ThreadLocalMap的, ...

    ThreadLocal应用示例及理解

    **线程局部变量(ThreadLocal)是Java编程中一个非常重要的工具类,它在多线程环境下提供了线程安全的数据存储。ThreadLocal并不是一个变量,而是一个类,它为每个线程都创建了一个独立的变量副本,使得每个线程都...

    ThreadLocal

    ThreadLocal通常被用来解决线程共享数据时可能出现的并发问题,避免了使用synchronized关键字进行同步控制的复杂性。 在Java中,ThreadLocal的工作原理是为每个线程创建一个单独的存储空间,每个线程可以独立地读写...

    ThreadLocal相关

    当多个线程访问同一个 ThreadLocal 变量时,每个线程将拥有其自己的变量副本,而不是共享同一个变量。 ThreadLocal 的特点 1. 线程独立:ThreadLocal 变量在线程之间是独立的,每个线程都有其自己的变量副本。 2. ...

    简单分析Java线程编程中ThreadLocal类的使用共

    ThreadLocal的实现原理是通过内部的ThreadLocalMap来存储每个线程的变量副本。这个映射表的键是ThreadLocal实例,值则是对应的线程局部变量。每个线程都维护了一个ThreadLocalMap实例,这样就确保了每个线程都有自己...

    java 中ThreadLocal本地线程和同步机制的比较

    与传统的同步机制(如`synchronized`关键字或`java.util.concurrent`包中的工具)相比,ThreadLocal的优势在于它不需要显式的锁来控制对共享变量的访问。每个线程都有自己的变量副本,因此在多线程环境中,它们不会...

    Java多线程 之 临界区、ThreadLocal.docx

    ThreadLocal是一种线程局部变量,它为每个线程都创建了一个独立的变量副本,从而避免了线程间的资源共享,减少了并发问题。每个线程都有自己的ThreadLocal变量,它们之间互不影响。ThreadLocal通常用于存储线程私有...

    ThreadLocal的几种误区

    当线程使用ThreadLocal时,它会查找或创建属于该线程的变量实例,而不是所有线程共享一个实例。 误区二:ThreadLocal与每个session相对应 在Java Web编程中,ThreadLocal与HTTP Session的概念混淆是常见的误解。...

    Java ThreadLocal详解_动力节点Java学院整理

    从本质上说,ThreadLocal是一种存储机制,它可以在每个线程中存储一个变量的副本,这样每个线程都可以访问自己的变量副本,而不需要与其他线程共享同一个变量。这种机制可以解决多线程编程中的线程安全问题,并且...

    Java非线程安全类变线程安全类.pdf

    非线程安全类的例子可以是 NotThreadSafe 类,该类有一个共享变量 state,当多个线程使用同一个 NotThreadSafe 类的一个对象时,也会共享该对象的 state 属性,故是非线程安全的。 但是,通过一些改造也可以将非...

    java事务 - threadlocal

    Java事务和ThreadLocal是两种在Java编程中至关重要的概念,它们分别用于处理多线程环境下的数据一致性问题和提供线程局部变量。 首先,我们来深入理解Java事务。在数据库操作中,事务是一系列操作的集合,这些操作...

    ThreadLocal的原理,源码深度分析及使用.docx

    简单来说,就是 ThreadLocal 为共享变量在每个线程中都创建一个副本,每个线程可以访问自己内部的副本变量。这样做的好处是可以保证共享变量在多线程环境下访问的线程安全性。 ThreadLocal 的使用 ThreadLocal ...

Global site tag (gtag.js) - Google Analytics