Java8——新时间日期API

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rubulai/article/details/89099572
问题

 老的时间日期API都存在线程安全问题,因为它们的实例的值都是可变的,多个线程操作同一个实例的时候就会产生线程安全问题。新的时间日期API解决了这个问题,每次改变值都会新创建一个时间日期等实例对象,这样就不存在多个线程操作同一个对象的问题,也就避免了线程安全问题。新的时间日期API都在java.time包下,该包下的实例都是不可变的,也就是说只要变化就会产生新的实例,类似于String,避免了线程安全问题。

示例

 1、多线程日期格式化:多个线程会同时操作同一个DateFormat实例,可能出现线程安全问题

public static void main(String args[]) throws InterruptedException, ExecutionException {
	//多个线程会同时操作该DateFormat实例,就可能出现线程安全问题
	DateFormat df = new SimpleDateFormat("yyyyMMdd");

	Callable<Date> task = new Callable<Date>() {
		@Override
		public Date call() throws Exception {
			return df.parse("20190408");
		}
	};
	//创建线程池
	ExecutorService pool = Executors.newFixedThreadPool(10);
	List<Future<Date>> results = new ArrayList<>();
	for (int i = 0; i < 10; i++) {
		//线程池中的线程执行任务,将结果放在Future中
		results.add(pool.submit(task));
	}

	for (Future<Date> future : results) {
		System.out.println(future.get());
	}

	pool.shutdown();
}

  某一次的运行结果:

Mon Apr 08 00:00:00 CST 2019
Mon Apr 08 00:00:00 CST 2019
Mon Apr 08 00:00:00 CST 2019
Mon Apr 08 00:00:00 CST 2019
Mon Apr 08 00:00:00 CST 2019
Mon Apr 08 00:00:00 CST 2019
Mon Apr 08 00:00:00 CST 2019
Mon Apr 08 00:00:00 CST 2019
Tue Jun 08 00:00:00 CST 2376
Tue Jun 08 00:00:00 CST 1

 2、使用ThreadLocal解决线程安全问题
  ①使用ThreadLocal编写工具类:ThreadLocal为变量在每个线程中都创建一个副本,每个线程只可以访问自己内部的副本变量,避免线程安全问题

public class DateFormatThreadLocal {
	
	private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
		protected DateFormat initialValue() {
			return new SimpleDateFormat("yyyyMMdd");
		}
	};

	public static Date format(String source) throws ParseException {
		return df.get().parse(source);
	}
}

   ThreadLocal的知识参考:深入剖析ThreadLocal
  ②使用本地线程变量中的DateFormat实例:避免线程安全问题

public static void main(String args[]) throws InterruptedException, ExecutionException {

		Callable<Date> task = new Callable<Date>() {
			@Override
			public Date call() throws Exception {
				//使用本地线程变量中的DateFormat实例
				return DateFormatThreadLocal.format("20190408");
			}
		};

		ExecutorService pool = Executors.newFixedThreadPool(10);
		List<Future<Date>> results = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			results.add(pool.submit(task));
		}

		for (Future<Date> future : results) {
			System.out.println(future.get());
		}

		pool.shutdown();
	}

 3、使用Java8的LocalDate,不需要使用ThreadLocal

public static void main(String args[]) throws InterruptedException, ExecutionException {

	DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");

	Callable<LocalDate> task = new Callable<LocalDate>() {
		@Override
		public LocalDate call() throws Exception {
			return LocalDate.parse("20190408", dtf);
		}
	};

	ExecutorService pool = Executors.newFixedThreadPool(10);
	List<Future<LocalDate>> results = new ArrayList<>();
	for (int i = 0; i < 10; i++) {
		results.add(pool.submit(task));
	}

	for (Future<LocalDate> future : results) {
		System.out.println(future.get());
	}
	pool.shutdown();
}

猜你喜欢

转载自blog.csdn.net/rubulai/article/details/89099572