jdk8的时间API是线程安全的,可以看下面的案例测试
package cn.wcj.jdk8.lambda.test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*
* <p>Title:DateFormatThreadLocal </p>
* <p>Description: 线程安全时间格式化</p>
* <p>Company:Software College </p>
* @author SuccessKey(WangCJ)
* @date 2017年6月21日 上午9:21:21
*/
public class DateFormatThreadLocal {
private static final ThreadLocal<DateFormat> THREAD_DF=new ThreadLocal<DateFormat>(){
@Override
public DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd") ;
}
} ;
public static final Date convert(String source)throws Exception{
return THREAD_DF.get().parse(source) ;
}
}
package cn.wcj.jdk8.lambda.test;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.junit.Test;
/**
*
* <p>Title:DateTest </p>
* <p>Description:测试JDK8新时间API </p>
* <p>Company:Software College </p>
* @author SuccessKey(WangCJ)
* @date 2017年6月21日 上午9:05:59
*/
public class DateTest {
//JDK7的时间API存在线程安全问题演示
//结果1 出现抢占造成结果不正确
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 6017
// Wed Jun 21 00:00:00 CST 6017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Fri Jun 21 00:00:00 CST 2120
// Sun Jun 21 00:00:00 CST 6201
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Sat Sep 21 00:00:00 CST 2193
//结果2 线程安全问题JUC
//java.util.concurrent.ExecutionException: java.lang.NumberFormatException
@Test
public void test1() throws Exception {
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd") ;
Callable<Date> task=new Callable<Date>() {
@Override
public Date call() throws Exception {
return sdf.parse("20170621");
}
};
ExecutorService threadPool = Executors.newFixedThreadPool(10);
List<Future<Date>> resultList = new ArrayList<Future<Date>>();
for(int x=0;x<12;x++)
resultList.add(threadPool.submit(task)) ;
for (Future<Date> future : resultList) {
System.out.println(future.get());
}
threadPool.shutdown();
}
//使用ThreadLocal改进JDK7时间线程安全问题
//运行结果
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
// Wed Jun 21 00:00:00 CST 2017
@Test
public void test2() throws Exception{
Callable<Date> task=new Callable<Date>() {
@Override
public Date call() throws Exception {
return DateFormatThreadLocal.convert("20170621") ;
}
};
ExecutorService threadPool = Executors.newFixedThreadPool(10);
List<Future<Date>> resultList = new ArrayList<Future<Date>>();
for (int i = 0; i <10; i++)
resultList.add(threadPool.submit(task)) ;
for (Future<Date> future : resultList)
System.out.println(future.get());
threadPool.shutdown();
}
//JDK8线程安全
// 2017-06-21
// 2017-06-21
// 2017-06-21
// 2017-06-21
// 2017-06-21
// 2017-06-21
// 2017-06-21
// 2017-06-21
// 2017-06-21
// 2017-06-21
@Test
public void test3()throws Exception{
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
Callable<LocalDate> task=()->LocalDate.parse("20170621", dtf) ;
ExecutorService threadPool = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> resultList = new ArrayList<Future<LocalDate>>();
for (int i = 0; i < 10; i++)
resultList.add(threadPool.submit(task)) ;
int len=resultList.size() ;
for (int i = 0; i < len; i++) {
System.out.println(resultList.get(i).get());
}
threadPool.shutdown();
}
//LocalDate、LocalTime、LocalDateTime
@Test
public void test4()throws Exception{
LocalDateTime localDateTime = LocalDateTime.now() ;
System.out.println(localDateTime) ;
System.out.println("-------------------------");
LocalDateTime localDateTime2 = LocalDateTime.of(2017, 6, 21, 10, 29,30);
System.out.println(localDateTime2) ;
System.out.println("-------------------------");
LocalDateTime plusYears = localDateTime2.plusYears(1);
System.out.println(plusYears);
System.out.println("-------------------------");
LocalDateTime minusMonths = localDateTime2.minusMonths(3);
System.out.println(minusMonths);
System.out.println("-------------------------");
System.out.println(localDateTime.getYear());
System.out.println(localDateTime.getMonthValue());
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getHour());
System.out.println(localDateTime.getMinute());
System.out.println(localDateTime.getSecond());
}
// Instant : 时间戳。 (使用 Unix 元年 1970年1月1日 00:00:00 所经历的毫秒值)
@Test
public void test5() {
Instant now = Instant.now() ; //默认使用 UTC 时区
System.out.println(now) ;
OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8)) ;
System.out.println(offsetDateTime) ;
System.out.println(now.getNano()) ;
Instant now2 = Instant.ofEpochSecond(5);
System.out.println(now2);
}
//Duration : 用于计算两个“时间”间隔
//Period : 用于计算两个“日期”间隔
@Test
public void test6() throws Exception{
Instant ins1 = Instant.now();
Thread.sleep(1000) ;
Instant ins2 = Instant.now();
System.out.println(Duration.between(ins1, ins2).getSeconds());
System.out.println("---------------------") ;
LocalDate ld1 = LocalDate.of(2014, 9, 5) ;
LocalDate ld2 = LocalDate.now() ;
Period period = Period.between(ld1, ld2);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
}
//TemporalAdjuster : 时间校正器
@Test
public void test7() {
LocalDateTime localDateTime = LocalDateTime.now() ;
System.out.println(localDateTime);
LocalDateTime localDateTime2 = localDateTime.withDayOfMonth(10) ;
System.out.println(localDateTime2);
LocalDateTime localDateTime3 = localDateTime.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
System.out.println(localDateTime3);
//自定义:下一个工作日
LocalDateTime localDateTime5 = localDateTime.with((l)->{
LocalDateTime localDateTime4 = (LocalDateTime) l ;
DayOfWeek dayOfWeek=localDateTime4.getDayOfWeek();
if(dayOfWeek.equals(DayOfWeek.FRIDAY)){
return localDateTime4.plusDays(3);
}else if(dayOfWeek.equals(DayOfWeek.SATURDAY)){
return localDateTime4.plusDays(2);
}else{
return localDateTime4.plusDays(1);
}
});
System.out.println(localDateTime5);
}
//DateTimeFormatter : 解析和格式化日期或时间
@Test
public void test8() {
DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE ;
LocalDateTime localDateTime = LocalDateTime.now() ;
String fmt = localDateTime.format(dtf) ;
System.out.println(fmt) ;
System.out.println("------------------------") ;
DateTimeFormatter dtf2 = DateTimeFormatter
.ofPattern("yyyy年MM月dd日 HH:mm:ss E") ;
LocalDateTime localDateTime2 = LocalDateTime.now() ;
System.out.println(localDateTime2);
String fmt2 = localDateTime2.format(dtf2) ;
System.out.println(fmt2) ;
System.out.println("------------------------") ;
LocalDateTime parse = LocalDateTime.parse(fmt2, dtf2) ;
System.out.println(parse) ;
}
//Asia/Shanghai
@Test
public void test9(){
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
availableZoneIds.stream()
.filter((t)->t.contains("Asia"))
.sorted()
.forEach(System.out::println);
}
@Test
public void test10(){
LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Shanghai")) ;
System.out.println(localDateTime) ;
}
}