`

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

    servlet与Struts action线程安全问题分析

    解决Servlet的线程安全问题通常有以下几种策略: 1. **避免使用实例变量**:尽可能使用局部变量,局部变量只存在于方法的执行上下文中,不会被多个线程共享,因此不存在线程安全问题。 2. **使用同步控制**:通过`...

    高并发之-SimpleDateFormat类的线程安全问题和解决方案.docx

    SimpleDateFormat类的线程安全问题和解决方案 SimpleDateFormat类的线程安全问题 SimpleDateFormat类是Java提供的日期时间转化类,用于将日期和时间类型的数据进行解析和格式化。在Java开发中,SimpleDateFormat类...

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

    在Java中,解决线程安全问题有多种方式: 1. **同步机制**:包括`synchronized`关键字和`java.util.concurrent`包中的工具类。`synchronized`可以保证在同一时刻,只有一个线程能执行特定代码块,防止数据不一致。...

    struts1,struts2,webwork,线程安全问题

    - 由于每次请求都会创建新的`Action`实例,因此`Action`类中的成员变量对于每个请求来说都是独立的,从而自动解决了线程安全问题。 - 这种做法降低了开发人员需要关注线程安全问题的复杂度,提高了开发效率。 ###...

    C# 高效线程安全,解决多线程写txt日志类.zip

    在C#中,实现线程安全通常有几种策略:锁(Lock)、Monitor、Mutex、Semaphore以及线程局部存储(ThreadLocal)等。 这个压缩包中的"TestConsoleApp"很可能是一个演示程序,展示了如何使用封装好的线程安全日志类。在...

    java后端面试问题整理

    - 使用ThreadLocal解决线程安全问题的场景。 4. **Java内存模型** - 描述堆内存和栈内存的区别。 - 讲解Java内存区域,包括堆、栈、方法区、程序计数器等。 - 分析JVM内存溢出(OOM)问题的常见原因及解决办法...

    java线程安全测试

    8. 线程局部变量(ThreadLocal):为每个线程创建独立的变量副本,避免了线程安全问题,但要注意,ThreadLocal变量会在线程结束时被垃圾回收,如果不及时清理可能导致内存泄漏。 测试线程安全通常包括模拟并发环境...

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

    3. 线程安全:ThreadLocal可以解决多线程编程中的线程安全问题,但是需要正确地使用ThreadLocal来避免线程安全问题。 ThreadLocal是一种非常有用的机制,可以解决多线程编程中的线程安全问题,但是需要正确地使用...

    ThreadLocal应用示例及理解

    - ThreadLocal不是线程同步机制,不能用来解决多个线程访问共享资源的问题。 - 不要将ThreadLocal用作全局变量,否则可能导致内存泄漏。 - 使用ThreadLocal时,要特别注意线程结束后的清理工作,防止内存泄漏。 - ...

    ThreadLocal

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

    Servlet线程安全问题.docx

    解决线程安全问题的方法 1. **使用同步机制**:可以使用`synchronized`关键字或者`java.util.concurrent`包中的工具类来控制对实例变量的访问,确保在同一时间只有一个线程能修改这些变量。 2. **避免使用实例变量*...

    构建线程安全应用程序

    ThreadLocal变量是另一种保证线程安全的方法,它为每个线程提供了一个变量的副本,使得每个线程都可以独立地修改自己的副本,而不会影响其他线程。ThreadLocal适用于那种线程间不需要共享数据,或者共享的数据需要以...

    Java多线程环境下SimpleDateFormat类安全转换

    2. 使用ThreadLocal解决线程安全问题 为了解决SimpleDateFormat类的线程安全问题,可以使用ThreadLocal类。ThreadLocal类可以使线程绑定到指定的对象,从而避免了线程之间的对象共享问题。在示例代码中,我们使用...

    day18 10.使用ThreadLocal来解决问题

    在Java编程中,ThreadLocal是线程局部变量的类,它为每个线程提供了一个独立的变量副本,...总的来说,ThreadLocal是Java中解决线程间数据隔离问题的强大工具,但在使用时需要注意内存管理和线程安全,避免潜在的问题。

Global site tag (gtag.js) - Google Analytics