实例讲解Java并发编程之ThreadLocal类

所属分类: 软件编程 / java 阅读数: 49
收藏 0 赞 0 分享

ThreadLocal类可以理解为ThreadLocalVariable(线程局部变量),提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回当前执行线程在调用set时设置的最新值。可以将ThreadLocal<T>视为 包含了Map<Thread,T>对象,保存了特定于该线程的值。

概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

模拟ThreadLocal

复制代码 代码如下:

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
 
public class SimpleThreadLocal<T> {
 private Map<Thread, T> valueMap = Collections
   .synchronizedMap(new HashMap<Thread, T>());
 
 public void set(T newValue) {
  valueMap.put(Thread.currentThread(), newValue); // ①键为线程对象,值为本线程的变量副本
 }
 
 public T get() {
  Thread currentThread = Thread.currentThread();
  T o = valueMap.get(currentThread); // ②返回本线程对应的变量
  if (o == null && !valueMap.containsKey(currentThread)) { // ③如果在Map中不存在,放到Map中保存起来。
   o = initialValue();
   valueMap.put(currentThread, o);
  }
  return o;
 }
 
 public void remove() {
  valueMap.remove(Thread.currentThread());
 }
 
 protected T initialValue() {
  return null;
 }
}

实用ThreadLocal
复制代码 代码如下:

class Count {
 private SimpleThreadLocal<Integer> count = new SimpleThreadLocal<Integer>() {
  @Override
  protected Integer initialValue() {
   return 0;
  }
 };
 
 public Integer increase() {
  count.set(count.get() + 1);
  return count.get();
 }
 
}
 
class TestThread implements Runnable {
 private Count count;
 
 public TestThread(Count count) {
  this.count = count;
 }
 
 @Override
 public void run() {
  // TODO Auto-generated method stub
  for (int i = 1; i <= 3; i++) {
   System.out.println(Thread.currentThread().getName() + "\t" + i
     + "th\t" + count.increase());
  }
 }
}
 
public class TestThreadLocal {
 public static void main(String[] args) {
  Count count = new Count();
  Thread t1 = new Thread(new TestThread(count));
  Thread t2 = new Thread(new TestThread(count));
  Thread t3 = new Thread(new TestThread(count));
  Thread t4 = new Thread(new TestThread(count));
  t1.start();
  t2.start();
  t3.start();
  t4.start();
 }
}

输出
复制代码 代码如下:

Thread-0    1th    1
Thread-0    2th    2
Thread-0    3th    3
Thread-3    1th    1
Thread-1    1th    1
Thread-1    2th    2
Thread-2    1th    1
Thread-1    3th    3
Thread-3    2th    2
Thread-3    3th    3
Thread-2    2th    2
Thread-2    3th    3

更多精彩内容其他人还在看

SpringBoot中使用Ehcache的详细教程

EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。这篇文章主要介绍了SpringBoot中使用Ehcache的相关知识,需要的朋友可以参考下
收藏 0 赞 0 分享

在idea 中添加和删除模块Module操作

这篇文章主要介绍了在idea 中添加和删除模块Module操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java spring整合junit操作(有详细的分析过程)

这篇文章主要介绍了java spring整合junit操作(有详细的分析过程),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解JAVA 弱引用

这篇文章主要介绍了 JAVA 弱引用的相关资料,帮助大家更好的理解和学习java引用对象,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

深入了解JAVA 虚引用

这篇文章主要介绍了JAVA 虚引用的相关资料,帮助大家更好的理解和学习JAVA,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

详解JAVA 强引用

这篇文章主要介绍了JAVA 强引用的相关资料,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

java中的按位与(&)用法说明

这篇文章主要介绍了java中的按位与(&)用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

深入了解JAVA 软引用

这篇文章主要介绍了JAVA 软引用的相关资料,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

利用MyBatis实现条件查询的方法汇总

这篇文章主要给大家介绍了关于利用MyBatis实现条件查询的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用MyBatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

Intellij IDEA 与maven 版本不符 Unable to import maven project See logs for details: No implementation for org.apache.maven.model.path.PathTranslator was bound

这篇文章主要介绍了Intellij IDEA 与maven 版本不符 Unable to import maven project See logs for details: No implementation for org.apache.maven.model.path.Pa
收藏 0 赞 0 分享
查看更多