package io.binghe.concurrent.lab06; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SimpleDateFormatTest05 { //执行总次数 private static final int EXECUTE_COUNT = 1000; //同时运行的线程数量 private static final int THREAD_COUNT = 20; private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){ @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; public static void main(String[] args) throws InterruptedException { final Semaphore semaphore = new Semaphore(THREAD_COUNT); final CountDownLatch countDownLatch = new CountDownLatch(EXECUTE_COUNT); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < EXECUTE_COUNT; i++){ executorService.execute(() -> { try { semaphore.acquire(); try { threadLocal.get().parse("2020-01-01"); } catch (ParseException e) { System.out.println("线程:" + Thread.currentThread().getName() + " 格式化日期失 败"); e.printStackTrace(); System.exit(1); }catch (NumberFormatException e){ System.out.println("线程:" + Thread.currentThread().getName() + " 格式化日期失 败"); e.printStackTrace(); System.exit(1); } semaphore.release(); } catch (InterruptedException e) { System.out.println("信号量发生错误"); e.printStackTrace(); System.exit(1); } countDownLatch.countDown(); }); } countDownLatch.await(); executorService.shutdown(); System.out.println("所有线程格式化日期成功"); } }
通过代码可以得知,将每个线程使用的SimpleDateFormat副本保存在ThreadLocal中,各个线程在使用时互不干扰,从而解决了线
程安全问题。
也可以直接使用DateTimeFormatter方式,DateTimeFormatter是Java8提供的新的日期时间API中的类,DateTimeFormatter类是线程安全的,可以在高并发场景下直接使用,格式化操作运行效率也比较高