SimpleDateFormat非线程安全测试及修改

1.出现异常

 

package demo4.jd;

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

public class MyThread extends Thread {

	private SimpleDateFormat sdf;
	private String dateString;

	public MyThread(SimpleDateFormat sdf, String dateString) {
		super();
		this.sdf = sdf;
		this.dateString = dateString;
	}

	@Override
	public void run() {
		try {
			Date dateRef = sdf.parse(dateString);
			String newDateString = sdf.format(dateRef).toString();
			if (!newDateString.equals(dateString)) {
				System.out.println(
						"ThreadName=" + this.getName() + "报错了 日期字符串:" + dateString + " 转换成的日期为:" + newDateString);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}

	}

}
package demo4.jd;

import java.text.SimpleDateFormat;

public class test22 {

	public static void main(String[] args) {

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

		String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", "2000-01-05",
				"2000-01-06", "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };

		MyThread[] threadArray = new MyThread[10];
		for (int i = 0; i < 10; i++) {
			threadArray[i] = new MyThread(sdf, dateStringArray[i]);
		}
		for (int i = 0; i < 10; i++) {
			threadArray[i].start();
		}

	}

}
控制台输出如下(具体每次运行结果可能有出入)

ThreadName=Thread-0报错了 日期字符串:2000-01-01 转换成的日期为:2000-01-04
ThreadName=Thread-1报错了 日期字符串:2000-01-02 转换成的日期为:2000-01-05
ThreadName=Thread-2报错了 日期字符串:2000-01-03 转换成的日期为:2000-01-05
ThreadName=Thread-6报错了 日期字符串:2000-01-07 转换成的日期为:2000-01-08

 

解决办法一

创建多个SimpleDateFormat类的实例

package tools;

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

public class DateTools {

	public static Date parse(String formatPattern, String dateString)
			throws ParseException {
		return new SimpleDateFormat(formatPattern).parse(dateString);
	}

	public static String format(String formatPattern, Date date) {
		return new SimpleDateFormat(formatPattern).format(date).toString();
	}

}
package test.run;

import java.text.SimpleDateFormat;

import extthread.MyThread;

public class Test {

	public static void main(String[] args) {

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

		String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
				"2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
				"2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };

		MyThread[] threadArray = new MyThread[10];
		for (int i = 0; i < 10; i++) {
			threadArray[i] = new MyThread(sdf, dateStringArray[i]);
		}
		for (int i = 0; i < 10; i++) {
			threadArray[i].start();
		}

	}
}
package extthread;

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

import tools.DateTools;

public class MyThread extends Thread {

	private SimpleDateFormat sdf;
	private String dateString;

	public MyThread(SimpleDateFormat sdf, String dateString) {
		super();
		this.sdf = sdf;
		this.dateString = dateString;
	}

	@Override
	public void run() {
		try {
			Date dateRef = DateTools.parse("yyyy-MM-dd", dateString);
			String newDateString = DateTools.format("yyyy-MM-dd", dateRef)
					.toString();
			if (!newDateString.equals(dateString)) {
				System.out.println("ThreadName=" + this.getName()
						+ "报错了 日期字符串:" + dateString + " 转换成的日期为:"
						+ newDateString);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}

	}

}

此种情况下控制台吗没有输出任何异常

 

解决异常方法二

ThreadLocal  类能使线程绑定到指定的对象,使用该类也可以解决多线程环境下SimpleDateFormat类处理错误的情况

package tools;

import java.text.SimpleDateFormat;

public class DateTools {

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

	public static SimpleDateFormat getSimpleDateFormat(String datePattern) {
		SimpleDateFormat sdf = null;
		sdf = tl.get();
		if (sdf == null) {
			sdf = new SimpleDateFormat(datePattern);
			tl.set(sdf);
		}
		return sdf;
	}

}
package test.run;

import java.text.SimpleDateFormat;

import extthread.MyThread;

public class Test {

	public static void main(String[] args) {

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

		String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
				"2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
				"2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };

		MyThread[] threadArray = new MyThread[10];
		for (int i = 0; i < 10; i++) {
			threadArray[i] = new MyThread(sdf, dateStringArray[i]);
		}
		for (int i = 0; i < 10; i++) {
			threadArray[i].start();
		}

	}
}
package extthread;

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

import tools.DateTools;

public class MyThread extends Thread {

	private SimpleDateFormat sdf;
	private String dateString;

	public MyThread(SimpleDateFormat sdf, String dateString) {
		super();
		this.sdf = sdf;
		this.dateString = dateString;
	}

	@Override
	public void run() {
		try {
			Date dateRef = DateTools.getSimpleDateFormat("yyyy-MM-dd").parse(
					dateString);
			String newDateString = DateTools.getSimpleDateFormat("yyyy-MM-dd")
					.format(dateRef).toString();
			if (!newDateString.equals(dateString)) {
				System.out.println("ThreadName=" + this.getName()
						+ "报错了 日期字符串:" + dateString + " 转换成的日期为:"
						+ newDateString);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}

	}

}

此种情况下控制台吗没有输出任何异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值