本地线程变量ThreadLocal (耗时工具)

本地线程变量类

package king;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

/**
 * TLTimeContainer为ThreadLocalTimeContainer(本地线程变量时间容器)的缩写
 * 说明:用来在任意一个方法内部置入recordTime(),以作片断时间点的记录
 * @author King
 * @time 2015/10/29
 */
public class TLTimeContainer {
	public static ThreadLocal<Map<String,List<Long>>> tl = new ThreadLocal<Map<String,List<Long>>>();

	/**
	 * 记录调用本方法的 类的方法 起,止时间
	 */
	public static void recordTime() {
		String clazz = Thread.currentThread().getStackTrace()[2].getClassName();
		String method = Thread.currentThread().getStackTrace()[2].getMethodName();
		Long l = System.currentTimeMillis();
		if (tl.get() == null) {
			Map<String,List<Long>> outerMap = new TreeMap<String,List<Long>>();
			List<Long> list1 = new ArrayList<Long>();
			list1.add(System.currentTimeMillis());
			outerMap.put("类"+clazz+"->"+"方法"+method+" ", list1);
			tl.set(outerMap);
		} else {
			Map<String,List<Long>> outerMap= tl.get();
			if(outerMap != null){
				List<Long> list2 = null;
				list2 = outerMap.get("类"+clazz+"->"+"方法"+method+" ");
				if(list2 != null){
					list2.add(System.currentTimeMillis());
				}else{
					list2 = new ArrayList<Long>();
					list2.add(System.currentTimeMillis());
					outerMap.put("类"+clazz+"->"+"方法"+method+" ", list2);
				}
			}
		}
	}

	/**
	 * 打印放入本容器中的 类的方法的起,止时间和耗时
	 */
	public static void print(){
		Map<String,List<Long>> outerMap= tl.get();
		if (outerMap != null) {
			for (Entry<String, List<Long>> entry : outerMap.entrySet()) {
//				   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
				   List<Long> list = entry.getValue();
				   Long start = list.get(0);
				   if(list.size() == 2){
					   Long end = list.get(1);
					   System.out.println(entry.getKey()+"起于:"+start);
					   System.out.println(entry.getKey()+"止于:"+end);
					   System.out.println(entry.getKey()+"耗时:"+(end-start));
				   }else{
					   System.out.println(entry.getKey()+"起于:"+start);
				   }
				   System.out.println("__________________________________________");
			}
		}
	}
}

  入口类

package king;

public class Entrance {
	public static void main(String[] args) throws Exception{
		method1();
		method2();
		TLTimeContainer.print();
	}

	public static void method1() throws Exception{
		TLTimeContainer.recordTime();//方法入口调用
		Thread.sleep(1000);
		TLTimeContainer.recordTime();//方法出口调用
	}

	public static void method2() throws Exception{
		TLTimeContainer.recordTime();//方法入口调用
		Thread.sleep(2000);
		TLTimeContainer.recordTime();//方法出口调用
	}
}

  运行后打印结果:

类compare.Other->方法m1 起于:1446088276528
类compare.Other->方法m1 止于:1446088277528
类compare.Other->方法m1 耗时:1000
__________________________________________
类compare.Other->方法m2 起于:1446088277528
类compare.Other->方法m2 止于:1446088279529
类compare.Other->方法m2 耗时:2001
__________________________________________

  

时间: 2024-11-01 15:55:00

本地线程变量ThreadLocal (耗时工具)的相关文章

Java并发学习之九——使用本地线程变量

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.如果创建一个类对象,实现Runnable接口,然后多个Thread对象使用同样的Runnable对象,全部的线程都共享同样的属性.这意味着,如果你在一个线程里改变一个属性,全部的线程都会受到这个改变的影响.如果希望程序里的哥哥线程的属性不会被共享,Java并发API提供了一个很清楚的机制叫本地线程变量. 2.Java并发API包括Inheritable ThreadLocal类提供线程创建线程的值的遗传性.如果线程A有一个本地线程变量,然

线程变量ThreadLocal的使用

我们有时候会通过token进行多次查询(猪:token是redis中的key),比如: 一次是在登录拦截器中,一次是在controller的业务中查询,这样存在性能和资源的浪费问题!!! 那么如何将拦截器中的数据传递到Controller中呢? 有两种方案: 1,将User对象放置到request对象中 2,使用ThreadLocal线程变量实现(在进入tomcat和产生响应前,对象都处于同一个线程中) 实现: 1,定义一个ThreadLocal相关的类 public class UserThr

线程本地变量ThreadLocal

一.本地线程变量使用场景 并发应用的一个关键地方就是共享数据.如果你创建一个类对象,实现Runnable接口,然后多个Thread对象使用同样的Runnable对象,全部的线程都共享同样的属性.这意味着,如果你在一个线程里改变一个属性,全部的线程都会受到这个改变的影响. 有时,你希望程序里的各个线程的属性不会被共享. Java 并发 API提供了一个很清楚的机制叫本地线程变量即ThreadLocal. 模拟ThreadLocal类实现:线程范围内的共享变量,每个线程只能访问他自己的,不能访问别的

线程隔离ThreadLocal

ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本. 从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思. 所以

本地线程-ThreadLocal

线程本地存储是一个自动化机制,可以为使用相同变量的每个不同的线程都创建不同的存储.简单来说,就是对于某个变量,针对不同的线程存储不同的值. 实例: import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * @Description * @Author

【java】ThreadLocal线程变量的实现原理和使用场景

一.ThreadLocal线程变量的实现原理 1.ThreadLocal核心方法有这个几个 get().set(value).remove() 2.实现原理 ThreadLocal在每个线程都会创建一个线程内对应的T的副本,本T数据可以在本线程内任何地方可以被使用.线程之间互相不影响,所以是线程安全的. 3.底层结构 ThreadLocal实现各个线程数据副本的存取,是通过操作它的内部类ThreadLocalMap,进行<k,v>键值对的存取和移除. 4.set(value)方法的底层 pub

Java中线程局部变量ThreadLocal使用教程及源码分析

在Java多线程编程中有时候会遇见线程本地局部变量ThreadLocal这个类,下面就来讲讲ThreadLocal的使用及源码分析. ThreadLocal 是Thread Local Varial(线程局部变量)的意思,每个线程在使用线程局部变量的时候都会为使用这个线程局部变量的线程提供一个线程局部变量的副本,使得每个线程都可以完全独立地操作这个线程局部变量,而不会与其他线程发生冲突,从线程的角度来看,每个线程都好像独立地拥有了这个线程局部变量.这样,看似每个线程都在并发访问同一个资源(线程局

[原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Hibernate中Session与本地线程绑定

------------------siwuxie095 Hibernate 中 Session 与本地线程绑定 1.Session 类似于 JDBC 的连接 Connection 2.Session 对象是单线程对象,只能自己使用,不能共用 将 Session 与本地线程绑定,保证 Session 对象绝对是一个单线程对象 3.Hibernate 帮助我们实现了 Session 与本地线程绑定(底层是 ThreadLocal) 4.获取与本地线程绑定的 Session (1)在 Hiberna