欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-31 18:37:22
threadlocal类可以理解为threadlocalvariable(线程局部变量),提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立...

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