`

通过代码,了解ThreadLocal

 
阅读更多

在看此代码时,先看http://www.iteye.com/topic/103804 

如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。  

 

 

 

package test1;

import java.util.Random;


/**
 * 2个线程,生成数据后,放入各自的线程中,使其他线程无法访问到。
 * @author Administrator
 *
 */
public class ThreadLocalTest {
	public static void main(String[] args) {
		new ThreadLocalTest().init();
	}
	
	private void init() {
		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					int data = new Random().nextInt();
					System.out.println("当前线程:" + Thread.currentThread().getName() + "  数据:" + data);
					
					MyObj obj = MyObj.getThreadInstance();
					obj.setAge(data);
					obj.setName("name" + data);
					
					new A().getData();
					new B().getData();
				}
			}){}.start();
		}
	}

	
	class A {
		public void getData () {
			MyObj obj = MyObj.getThreadInstance();
			System.out.println("A: 当前线程:" + Thread.currentThread().getName() + "  数据:" + obj.toString());
		}
	}
	
	class B {
		public void getData () {
			MyObj obj = MyObj.getThreadInstance();
			System.out.println("B: 当前线程:" + Thread.currentThread().getName() + "  数据:" + obj.toString());
		}
	}
	
	
}


class MyObj {
	private MyObj(){};
	
	private static ThreadLocal<MyObj> map = new ThreadLocal<MyObj>();
	
	
	/*
	 * 必须加synchronized(张孝祥老师说此处不需加synchronized是错误的)
	 * 如不加:线程0进入,发现instance为null,刚要实例化时,cpu给了线程1,线程1实例化完instance,
	 * 刚要返回,cpu给了线程0,线程0此时并未实例化instance,但发现已经实例化了,所以不再走map.set()方法,
	 * 导致MyObj obj = MyObj.getThreadInstance(); 从map中取出当前线程的instance为null
	 */
	public static synchronized MyObj getThreadInstance() {
		instance = map.get();
		if (instance == null) {
			instance = new MyObj();
			map.set(instance);
		}
		return instance;
	}
	
	private static MyObj instance;
	
	private int age;
	
	private String name;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public String toString() {
		String str = String.format("名字: [%s], 年龄: [%d]", this.name, this.age);
		return str;
	}
	
	
	
}

 

 

分享到:
评论

相关推荐

    ThreadLocal应用示例及理解

    **线程局部变量(ThreadLocal)是Java编程中一个...了解并熟练掌握ThreadLocal可以帮助我们编写出更高效、更安全的多线程代码。在Java并发编程中,ThreadLocal是一个不可或缺的工具,尤其在需要线程私有数据的场景下。

    设计模式及ThreadLocal资料

    设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的模板。...在实际开发中,灵活运用设计模式可以提高代码质量,而ThreadLocal则为处理多线程环境下的数据隔离提供了一种有效手段。

    从ThreadLocal的使用到Spring的事务管理

    首先,让我们了解ThreadLocal。ThreadLocal是Java提供的一种线程绑定变量的工具类,它允许我们在一个线程内部创建独立的变量副本。每个线程都有自己的ThreadLocal实例,并且只能访问自己的副本,不会与其他线程的...

    ThreadLocal的用处

    ThreadLocal是Java编程语言中的一个强大工具,它主要用于在多线程环境中为每个线程提供独立的变量副本。这个机制确保了线程之间的数据隔离,避免了共享...了解其工作原理和最佳实践对于编写高质量的并发代码至关重要。

    Spring事务处理-ThreadLocal的使用

    声明式事务管理是通过注解或XML配置来控制事务边界,而编程式事务管理则是在代码中显式调用`TransactionTemplate`或`PlatformTransactionManager`进行控制。 ThreadLocal是Java提供的一种线程局部变量,每个线程都...

    ThreadLocal和事务

    首先,让我们深入了解`ThreadLocal`。ThreadLocal是Java提供的一个线程绑定变量的类,它为每个线程创建了一个独立的变量副本。这意味着每个线程都有自己的变量实例,不会相互影响。在Web应用中,尤其是在多线程环境...

    ThreadLocal

    ThreadLocal是Java编程语言中的一个类,用于在多线程环境中提供线程局部变量。它是一种强大且实用的工具,可以确保每个线程都拥有自己...了解ThreadLocal的底层实现和工作原理对于优化并发代码和防止内存泄漏至关重要。

    Java并发编程中ThreadLocal的原理与应用分析

    其他说明:为了更好地理解ThreadLocal的工作机制,建议实际动手尝试文中提供的实例代码,同时注意不同版本JDK之间的差异可能会导致部分细节有所变化。对于追求高性能并发应用开发的技术人员而言,了解和运用...

    ThreadLocal分析

    过度依赖ThreadLocal可能导致代码难以理解和维护,且可能导致内存泄漏。在设计和使用ThreadLocal时,需要谨慎评估其必要性和潜在风险。 在分析ThreadLocal源码时,可以了解到它如何在内部实现线程隔离,以及...

    JavaEE DBUtil结合ThreadLocal的一个案例

    通过分析这些代码,可以更深入地了解如何在实际项目中结合使用DBUtil和ThreadLocal。 总的来说,JavaEE中的DBUtil结合ThreadLocal能够有效地提高数据库操作的效率和安全性,尤其是在多线程环境下。它通过线程局部...

    8个案例详解教会你ThreadLocal.docx

    通过以上介绍,我们可以了解到 `ThreadLocal` 在处理多线程环境中提供了独特的数据隔离机制,常用于创建线程安全的工具类实例,或者在每个线程内部保存全局变量。正确使用和管理 `ThreadLocal` 是避免潜在问题的关键...

    快速了解Java中ThreadLocal类

    例如在上述代码中,线程A和线程B分别设置了自己的ThreadLocal变量值,互不影响。 2. **线程安全性**:由于线程间的数据隔离,ThreadLocal变量无需进行额外的同步控制,从而降低了同步带来的开销,提升了程序性能。 ...

    Android 详解ThreadLocal及InheritableThreadLocal

    具体差异需要查看对应版本的源代码来了解。 理解ThreadLocal的关键在于认识到它是线程局部的,每个线程都有自己的独立副本,而不是所有线程共享一个全局变量。这使得ThreadLocal成为在多线程环境下维护线程安全状态...

    dotnet 在析构函数调用 ThreadLocal 也许会抛出对方已释放.rar

    在.NET开发中,`dotnet`是一个核心框架,它提供了丰富的...了解这些概念和最佳实践,有助于编写更健壮和安全的.NET代码。在使用`ThreadLocal`时,务必考虑到它的生命周期和垃圾收集机制,以防止出现意外的错误和异常。

    Java代码与架构之完美优化配套代码.rar

    通过学习和实践这些知识点,开发者可以逐步提升Java代码和架构的优化能力,确保软件系统的高效运行。这个压缩包中的配套代码将为读者提供一个动手实践的平台,加深对书中学到理论的理解,帮助读者更好地将理论知识...

    java代码规范——很经典的一本书

    14. **并发编程**:处理多线程时,了解并发原语,如synchronized、volatile、ThreadLocal等,并谨慎使用。 15. **性能优化**:避免过早优化,但也要关注性能瓶颈,使用适当的设计模式和数据结构,以及避免不必要的...

    郝斌Java源代码下

    了解如何正确地捕获和处理异常是编写健壮代码的关键。 3. **集合框架**:在【86-88】和【92-94】源代码中,可能涉及到ArrayList、LinkedList、HashMap等集合类的使用,以及遍历、添加、删除元素的方法。集合框架是...

    Android 中ThreadLocal的深入理解

    ThreadLocal在Android开发中是一个非常重要的工具类,用于在多线程环境中提供线程局部变量。它的核心概念在于,每个...了解ThreadLocal的工作原理和使用场景,可以帮助开发者更好地管理和优化多线程环境中的数据存储。

    ThreadLocal、InheritableThreadLocal详解

    在上述代码中,`thl`在每个线程中都有独立的副本,线程A和线程B可以通过`thl.set()`和`thl.get()`分别设置和获取自己的变量,实现数据隔离。 **InheritableThreadLocal** InheritableThreadLocal与ThreadLocal非常...

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

    1. **数据隔离**:ThreadLocal确保了每个线程都有自己的变量副本,避免了多线程之间的数据竞争,从而提高了代码的安全性和可维护性。 2. **简化同步管理**:使用ThreadLocal,开发者无需担心同步问题,因为每个线程...

Global site tag (gtag.js) - Google Analytics