聊聊SimpleDateFormat

在Java中我们对于SimpleDateFormat这个类应该很熟悉了,就是对时间进行处理的一个相关类,前几天我读文档的时候发现其实线程不安全的,这就来问题了,假如在网站或者系统负载比较大的时候,假如用到这个类,那我们应该如何处理呢?如何编写线程安全级别的程序呢?

下面我们先来看一下最简单粗暴的写法:

package com.study.demo1;

public class TestSimpleDateFormat extends Thread {

SimpleDateFormat sdf  = new SimpleDateFormat("yyyy-MM-dd");
@Override
public void run() {
   System.out.println(sdf.parse(parseTime));
}


public static void main(String[] args) {
	
	/*
	 * The first method
	 * */
	for(int i=0;i<3;i++){
		TestSimpleDateFormat tsdf = new TestSimpleDateFormat();
		tsdf.start();
	}
}
}

这是最简单的一种写法,可是我们会发现一个问题,就是我们为每个线程都新建了一个对象,这个在高访问的系统中无疑使不可行的,会增加虚拟机的负载能力。

下面看第二种写法:

1、写一个时间处理的工具类:

package com.study.demo1;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateFormatUtils {

static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

public void getParse() {
	synchronized (sdf) {
		if (null == sdf) {
			sdf = new SimpleDateFormat("yyyy-MM-dd");
			System.out.println("Create a new instance");
		}
		try {
			System.out.println(sdf.parse("2014-01-01"));
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
}
}

2、测试类

package com.study.demo1;


public class TestSimpleDateFormat extends Thread {

static DateFormatUtils dfu = new DateFormatUtils();
@Override
public void run() {
	dfu.getParse();
}


public static void main(String[] args) {
	
	/*
	 * The second method
	 * */
	for(int i=0;i<3;i++){
		TestSimpleDateFormat tsdf = new TestSimpleDateFormat();
		tsdf.start();
	}	
}
}

当然这里使用了同步机制,其实变相的是一种单例的实现。

后来我去网上看了相关的帖子,其实还有更进一步的写法,通过ThreadLocal来实现相关的线程安全,具体代码如下:

1、写一个时间处理的工具类:

package com.study.demo1;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateFormatUtils {

private static ThreadLocal<DateFormat> tl = new ThreadLocal<DateFormat>();

public static DateFormat getDateFormat() {
	DateFormat df = tl.get();
	if (null == df) {
		df = new SimpleDateFormat("yyyy-MM-dd");
		tl.set(df);
	}
	return df;
}

public void getParse2() {

	try {
		System.out.println(getDateFormat().parse("2014-01-01"));
	} catch (ParseException e) {
		e.printStackTrace();
	}
}
}

2、测试类

package com.study.demo1;


public class TestSimpleDateFormat extends Thread {

static DateFormatUtils dfu = new DateFormatUtils();
@Override
public void run() {
	dfu.getParse2();
}


public static void main(String[] args) {
	
	/*
	 * The second method
	 * */
	for(int i=0;i<3;i++){
		TestSimpleDateFormat tsdf = new TestSimpleDateFormat();
		tsdf.start();
	}	
}
}

以上几种方法都可以达到一定的线程安全,不过还是要具体情况具体使用了,我觉得也并不是一定要追求极致,看系统的负载能力等要求,选择一定的适合的方法就行了。

(完)

`



Previous     Next
mjgao /