在结合多线程使用的使用,SimpleDateFormat使用会出现一些问题。其本身是不适用于多线程的场景,但是我们依然可以借助一些办法来操作。这里有三种方法把线程优化:局部变量、new和同步锁。相信很多人没接触过这类使用,下面我们就这三种方法分别展开讲解,试图SimpleDateFormat在多线程中的不安全性。
1.局部变量
for (int i = 0; i < 100; i++) { //获取当前时间 Calendar calendar = Calendar.getInstance(); int finalI = i; pool.execute(() -> { // SimpleDateFormat声明成局部变量 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //时间增加 calendar.add(Calendar.DATE, finalI); //通过simpleDateFormat把时间转换成字符串 String dateString = simpleDateFormat.format(calendar.getTime()); //把字符串放入Set中 dates.add(dateString); //countDown countDownLatch.countDown(); }); }
2.new
每次使用时new一个SimpleDateFormat 的 实例,这样可以保证每个实例使用自己的Calendar实例,但是每次使用都需要new一个对象,并且使用后由于没有其他引用,又需要回收,开销会很大。
public class DateUtils { public static Date parseString( String datetime) throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); return format.parse(datetime); } }
3.同步锁
通过加锁,使多个线程排队顺序执行。避免了并发导致的线程安全问题。
for (int i = 0; i < 100; i++) { //获取当前时间 Calendar calendar = Calendar.getInstance(); int finalI = i; pool.execute(() -> { //加锁 synchronized (simpleDateFormat) { //时间增加 calendar.add(Calendar.DATE, finalI); //通过simpleDateFormat把时间转换成字符串 String dateString = simpleDateFormat.format(calendar.getTime()); //把字符串放入Set中 dates.add(dateString); //countDown countDownLatch.countDown(); } }); }
其实以上代码还有可以改进的地方,就是可以把锁的粒度再设置的小一点,可以只对simpleDateFormat.format这一行加锁,这样效率更高一些。
以上就是java中SimpleDateFormat线程优化的三种方法,当然还有常见的处理方法能解决不安全问题,本篇介绍这三种后就不再过多阐述,想学习的可以查询下资料。