`

ThreadLocal解决线程安全问题

    博客分类:
  • java
阅读更多
//以下代码存在问题
public class ThreadLocalDemo {
	//private static ThreadLocal<String> tl = new ThreadLocal<String>(); //①

	private String name; //线程不安全的变量
	
	public String getName() {
		return name;
		//return tl.get(); //②
	}
	
	public void setName(String name) {
		this.name = name;
		//tl.set(name); //③
	}

	public static void main(String[] args) {
		ThreadLocalDemo demo = new ThreadLocalDemo(); //一个SingleTon实例
		//模拟并发访问(第二个参数表示用户访问时输入的用户名)
		VisitThread visitor1 = new VisitThread(demo, "Bruce"); //访问者1
		VisitThread visitor2 = new VisitThread(demo, "Phil"); //访问者2
		VisitThread visitor3 = new VisitThread(demo, "David"); //访问者3
		visitor1.start();
		visitor2.start();
		visitor3.start();
	}

	/**
	 * 访问线程(一个线程代表一个并发时的不同用户访问)
	 */
	private static class VisitThread extends Thread {
		private ThreadLocalDemo demo;
		private String name;
		public VisitThread(ThreadLocalDemo demo, String name) {
			this.demo = demo;
			this.name = name;
		}
		public void run() {
			demo.setName(name);
			String tempName = name; //tempName是线程安全的
			//让程序暂停一秒,以便显示线程不安全而出现的错误
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("Thread[" + this.currentThread().getName() + "] name[" + demo.getName() + "]" + " (should be[" + tempName + "])");
		}
	}
}

 

运行输出如下

Thread[Thread-0] name[David] (should be[Bruce])
Thread[Thread-2] name[David] (should be[David])
Thread[Thread-1] name[David] (should be[Phil])

 

问题:可以看到三个用户输入的名字都变成了"David"(demo.getName()  = "David")

 

要解决以上问题,可以选择用synchronized同步,这样就影响了并发性能。

 

我们也可以选择一种不影响并发性能的解决方案。把①的注释放开,getName() 和setName()换成②和③,这样好能解决并发问题。

 

再次运行输出如下

Thread[Thread-2] name[David] (should be[David])
Thread[Thread-1] name[Phil] (should be[Phil])
Thread[Thread-0] name[Bruce] (should be[Bruce])

 

以上主要是举个并发问题的例子,如果想更了解ThreadLocal,可以看下面的文章

http://www.builder.com.cn/2007/0529/404695.shtml

 

0
0
分享到:
评论

相关推荐

    ThreadLocal:如何优雅的解决SimpleDateFormat多线程安全问题

    目录SimpleDateFormat诡异bug复现SimpleDateFormat诡异bug字符串日期转Date日期(parse)Date日期转String类型(format)SimpleDateFormat出现...注意事项使用ThreadLocal解决SimpleDateFormat线程安全问题总结...

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

    主要介绍了Java ThreadLocal 线程安全问题解决方案的相关资料,需要的朋友可以参考下

    java多线程安全性基础介绍.pptx

    java多线程安全性基础介绍 线程安全 正确性 什么是线程安全性 原子性 竞态条件 i++ 读i ++ 值写回i 可见性 JMM 由于cpu和内存加载速度的差距,在两者之间增加了多级缓存导致,内存并不能直接对cpu可见。 ...

    Spring.3.x企业应用开发实战(完整版).part2

    9.2.5 Spring使用ThreadLocal解决线程安全问题 9.3 Spring对事务管理的支持 9.3.1 事务管理关键抽象 9.3.2 Spring的事务管理器实现类 9.3.3 事务同步管理器 9.3.4 事务传播行为 9.4 编程式的事务管理 9.5 使用XML...

    Spring3.x企业应用开发实战(完整版) part1

    9.2.5 Spring使用ThreadLocal解决线程安全问题 9.3 Spring对事务管理的支持 9.3.1 事务管理关键抽象 9.3.2 Spring的事务管理器实现类 9.3.3 事务同步管理器 9.3.4 事务传播行为 9.4 编程式的事务管理 9.5 使用XML...

    基于Java多线程同步的安全性研究

    解决Java多线程同步的方法是在需要同步的方法签名中加入synchronized关键字,...为解决多个线程对同一变量进行访问时可能发生的安全性问题,不仅可以采用同步机制,更可以通过JDK中加入的ThreadLocal来保证更好的并发性。

    java学习整理文档.docx

    关于单例bean的线程安全和并发问题需要开发者自行去搞定 最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”或者在Bean对象中尽量避免定义可变的成员变量(使用局部变量)。 使用同步...

    Java并发编程(学习笔记).xmind

    委托是创建线程安全类的最有效策略,只需要让现有的线程安全类管理所有的状态 在现有线程安全类中添加功能 将同步策略文档化 基础构建模块 同步容器类 分类 Vector Hashtable 实现...

    leetcode下载-JavaTopic:Java面试题总结

    spring单实例如何解决有状态bean的线程安全问题的? ThreadLocal的原理? spring事务7种传播特性和隔离级别的理解? spring boot的启动过程 spring事务实现的原理 aop切面 如何解决spring循环依赖问题? Redis篇: ...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【多线程】什么是线程安全与非线程安全 72 【多线程】多线程的实现方式Thread、Runnable、Callable 72 【多线程】实现Runnable接口与继承Thread类比较 73 【多线程】线程状态转换 74 【多线程】线程的调度 75 线程...

    day020-继承加强和设计模式代码和笔记.rar

    1. 单元测试:(掌握) 1. 写一个单元测试类,命名方式:XxxTest(测试类没有main方法) 2.... 选中项目,右键 =&gt; ... 解决了线程安全问题,通过线程隔离有安全问题的数据实现的,底层是通过map保存线程id和值的。

    ajax调用java实例源码-java-curl:纯JavaCURL实现

    使用ThreadLocal解决了标准Java中cookies只能全局存储的问题,cookies对于每个线程都是隔离维护的。 线程中的cookie-store可以序列化保存,方便设置cookie池。 支持HTTPS; 支持自签名证书(JKS/BKS); 支持忽略...

    java随机数

    幸运的是,java.util.Random是线程安全的,所以不存在多个线程调用会破坏种子(seed)的风险。 另一个值得考虑的是多线程java.lang.ThreadLocal的实例。偷懒的做法是通过Java本身API实现单一实例,当然你也可以确保每...

    互联网创意产品众筹平台

    │ 02-ThreadLocal解决线程资源共享 │ 03-弹层组件layer使用. [- l; o" [6 F# U# ~. a7 c │ 04-用户分页查询-分析-同步请求方式 │ 05-用户分页查询-分析-同步请求代码开发 │ 06-用户分页查询-分页导航条# a1 W7 ...

    Java常见面试题208道.docx

    30.哪些集合类是线程安全的? 31.迭代器 Iterator 是什么? 32.Iterator 怎么使用?有什么特点? 33.Iterator 和 ListIterator 有什么区别? 34.怎么确保一个集合不能被修改? 三、多线程 35.并行和并发有什么区别?...

    J2EE开发全程实录(JAVA项目开发)

    6.4.6 安全问题... 100 第7章 元数据引擎.... 102 7.1 MDA概述... 102 7.2 关于元数据... 104 7.2.1 元数据示例... 105 7.2.2 元元数据... 108 7.2.3 设计时与运行时... 108 7.2.4 元数据设计的基本原则... 109 ...

Global site tag (gtag.js) - Google Analytics