ThreadLocal实现在同一个线程内的数据共享

1、了解ThreadLocal类.

      查看相关api文档,对该类描述如下:

      该类提供了线程局部变量。这些变量不同于它们的普通对应物,因为访问一个变量(通过其 getset 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的私有静态字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

 

2、实验目的:在不同模块里共享同一个变量的引用,为了方便理解,你可以把不同的模块理解为不同的类,但模块有更广的概念.

     步骤:

     1、先定义一个自己的事务类MyTransaction,在该类中定义一个提交事务的方法commit();

     2、再定义一个自己的Session类MySession,在该类中定义一个beginTransaction方法和getTransaction方法,并定义一个ThreadLocal类的私有静态字段.

     3、分别定义两个模块: A类各B类

     具体模拟代码如下:

package test;
public class ThreadLocalTest {
	public static void main(String[] args) throws InterruptedException {
		final A a = new A();
		final B b = new B();
		for(int i=0;i<3;i++){
		new Thread(){
			public void run(){
				MySession session = new MySession(new MyTransaction());
				MyTransaction tx = session.beginTransaction();
				System.out.println("打开事务:"+tx);
				a.modify();
				b.save();
				tx.commit();//提交事务
				System.out.println();
			}	
		}.start();
		Thread.sleep(1000);
		}
	}
}	
	/**不同模块共享同一个变量*/
	class A{
		public void modify(){
			System.out.println(Thread.currentThread()+": A 得到的事务: "+MySession.getTransaction());
		}
	}
	class B{
		public void save(){
			System.out.println(Thread.currentThread()+": B 得到的事务: "+MySession.getTransaction());
		}
	}
	
	class MyTransaction{
		public void commit(){
			System.out.println("提交事务:"+this);
		}
	}
	class MySession{
		private static MyTransaction transaction= null;
		private static ThreadLocal threadLocal = new ThreadLocal();
		public MySession(MyTransaction transaction){
			this.transaction = transaction;
		}
		public MyTransaction beginTransaction(){
			transaction = (MyTransaction)threadLocal.get();
			if(transaction==null){
				transaction = new MyTransaction();
				threadLocal.set(transaction);
			}
			return transaction;
		}
		public static MyTransaction getTransaction(){
			return (MyTransaction)threadLocal.get();
		}
	}

 

打印结果如下:

打开事务:test.MyTransaction@3e25a5
Thread[Thread-0,5,main]: A 得到的事务: test.MyTransaction@3e25a5
Thread[Thread-0,5,main]: B 得到的事务: test.MyTransaction@3e25a5
提交事务:test.MyTransaction@3e25a5

打开事务:test.MyTransaction@19821f
Thread[Thread-1,5,main]: A 得到的事务: test.MyTransaction@19821f
Thread[Thread-1,5,main]: B 得到的事务: test.MyTransaction@19821f
提交事务:test.MyTransaction@19821f

打开事务:test.MyTransaction@addbf1
Thread[Thread-2,5,main]: A 得到的事务: test.MyTransaction@addbf1
Thread[Thread-2,5,main]: B 得到的事务: test.MyTransaction@addbf1
提交事务:test.MyTransaction@addbf1

 3、ThreadLocal的应用场景

     1、如:银行转帐包含一系列操作:把转出帐户的余额减少,把转入帐户的余额增加,这两个操作要在同一个事务中完成,它们必须使用相同的数据库连接对象,转入和转出操作的代码分别是两个不同的帐户对象的方法.

 

     2、又如:Struts2的ActionContex,同一段代码被不同的线程调用运行时,该项代码操作的数据是每个线程各自状态和数据,对于不同的线程来说,getContext方法拿到的对象都不相同,对同一个线程来说,不管调用getContext方法多少次和哪个模块getContext方法,拿到的都是同一个对象.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值