源码研究和case分享

 

项目终于接近尾声,下周上线,没有太多事情,为了保证代码质量,所以现在更多的事情是codereview,顺便也补充下能量,首先分享一个压力测试下的case吧,

simpleDateFormat作为全局变量时,存在线程不安全问题,容易引起值覆盖问题,当然在使用全局变量,高并发环境下又没使用线程安全的情况下,都会导致这个问题,虽然源代码很明白可以觉察这个问题,但还是贴上代码更有说服力:

 

 

package reference.unsafe;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Format {
	
	private static  DateFormat   dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	
	public static  String  formatYmdHms(Date date){
		
		try {
			return dateFormat.format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	
	public static String formatYmdHms1(Date date){
		try {
			return dateFormat.format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
		
	}
	
	public static void main(String[] args) {
		
		System.out.println(new Date());
		
	}
	

}


-----------------------------------华丽分割------------------------------------------


package reference.unsafe;

import java.util.Calendar;
import java.util.Date;

public class Test {
	
	
	
	public static void main(String[] args) {
		
		Test tt = new Test();
		for (int i = 0; i < 50; i++) {
			tt.new formatD().start();
			tt.new formatM().start();
		}
		
	}
	
	class  formatD extends Thread{
		
		public formatD(){
			super.setName("QQ");
		}
		
		public void run(){
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("线程名称【"+Thread.currentThread().getName()+"】,当前时间:【"+new Date()+"】,格式后:【"+Format.formatYmdHms(new Date())+"】");
		    
		}
		
	}
	
   class  formatM extends Thread{
		
	   public formatM(){
			super.setName("PP");
		}
	   
		public void run(){
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.HOUR_OF_DAY, 2);
			System.out.println("线程名称【"+Thread.currentThread().getName()+"】,当前时间:【"+new Date()+"】,格式后:【"+Format.formatYmdHms1(calendar.getTime())+"】");
		    
		}
		
	}
	
	

}
再分析下jdk下simpleDateFormat源码
 private StringBuffer format(Date date, StringBuffer toAppendTo,
                                FieldDelegate delegate) {
        // Convert input date to time field list
        calendar.setTime(date);
很容易看出多个线程都进入到format方法,更改了calendar,问题就发生了,如何解决这个问题呢?这里给出两种
解决方案吧,首先肯定是局部变量如:return new SimpleDateFormat("yyyy.MM.dd").format(new Date());

也可以使用副本:
 private static ThreadLocal ymdFormatThreadLocal = new ThreadLocal() {
	  protected  Object initialValue() {
	   return new SimpleDateFormat("yyyyMMdd");
	  }
	 };
这里再贴上一遍参考文章,他的系列代码之丑文章,不错,作为java开发人员可以参考,引以为戒
http://www.infoq.com/cn/news/2012/06/ugly-code-12
最后为了给自己补充能量,贴上两个开源代码svn,有兴趣的同学可以研究下
http://svn.apache.org/repos/asf/tomcat/tc7.0.x/trunk
https://github.com/taobao/tedis






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值