分享阿里 P8 高階架構師吐血總結的 《Java 核心知識體系&面試資料.pdf》
據說是阿里 P8 級高階架構師吐血總結的一份 Java 核心知識。pdf, 內容覆蓋很廣,Java 核心基礎、Java 多執行緒、高併發、Spring、微服務、Netty 與 RPC、Zookeeper、Kafka、RabbitMQ、Habase、設計模式、負載均衡、分散式快取、Hadoop、Spark、Storm、雲計算等。
另外,附送 100G 學習、面試影片文件喲~
獲取方式:【
關注 + 轉發
】後,
私信
我,回覆關鍵字【
資源
】,即可
免費無套路獲取
哦~
以下是資源的部分目錄以及內容截圖:
重要的事再說一遍,獲取方式:【
關注 + 轉發
】後,
私信
我,回覆關鍵字【
資源
】,即可
免費無套路獲取
哦~
正文開始
在專案開發過程中經常遇到時間處理,但是你真的用對了嗎,理解阿里巴巴開發手冊中禁用static修飾SimpleDateFormat嗎
透過閱讀本篇文章你將瞭解到:
為什麼需要LocalDate、LocalTime、LocalDateTime【java8新提供的類】
java8新的時間API的使用方式,包括建立、格式化、解析、計算、修改
為什麼需要LocalDate、LocalTime、LocalDateTime
Date如果不格式化,打印出的日期可讀性差
Tue Sep 10 09:34:04 CST 2019複製程式碼
使用SimpleDateFormat對時間進行格式化,但SimpleDateFormat是執行緒不安全的 SimpleDateFormat的format方法最終呼叫程式碼:
private StringBuffer format(Date date, StringBuffer toAppendTo, FieldDelegate delegate) { // Convert input date to time field list calendar。setTime(date); boolean useDateFormatSymbols = useDateFormatSymbols(); for (int i = 0; i < compiledPattern。length; ) { int tag = compiledPattern[i] >>> 8; int count = compiledPattern[i++] & 0xff; if (count == 255) { count = compiledPattern[i++] << 16; count |= compiledPattern[i++]; } switch (tag) { case TAG_QUOTE_ASCII_CHAR: toAppendTo。append((char)count); break; case TAG_QUOTE_CHARS: toAppendTo。append(compiledPattern, i, count); i += count; break; default: subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols); break; } } return toAppendTo; }複製程式碼
calendar是共享變數,並且這個共享變數沒有做執行緒安全控制。當多個執行緒同時使用
相同的SimpleDateFormat物件
【如用static修飾的SimpleDateFormat】呼叫format方法時,多個執行緒會同時呼叫calendar。setTime方法,可能一個執行緒剛設定好time值另外的一個執行緒馬上把設定的time值給修改了導致返回的格式化時間可能是錯誤的。在多併發情況下使用SimpleDateFormat需格外注意 SimpleDateFormat除了format是執行緒不安全以外,parse方法也是執行緒不安全的。parse方法實際呼叫alb。establish(calendar)。getTime()方法來解析,alb。establish(calendar)方法裡主要完成了
重置日期物件cal的屬性值
使用calb中中屬性設定cal
返回設定好的cal物件
但是這三步不是原子操作
多執行緒併發如何保證執行緒安全 - 避免執行緒之間共享一個SimpleDateFormat物件,每個執行緒使用時都建立一次SimpleDateFormat物件 => 建立和銷燬物件的開銷大 - 對使用format和parse方法的地方進行加鎖 => 執行緒阻塞效能差 - 使用ThreadLocal保證每個執行緒最多隻建立一次SimpleDateFormat物件 => 較好的方法
Date對時間處理比較麻煩,比如想獲取某年、某月、某星期,以及n天以後的時間,如果用Date來處理的話真是太難了,你可能會說Date類不是有getYear、getMonth這些方法嗎,獲取年月日很Easy,但都被棄用了啊
Come On 一起使用java8全新的日期和時間API
LocalDate
只會獲取年月日
建立LocalDate
//獲取當前年月日LocalDate localDate = LocalDate。now();//構造指定的年月日LocalDate localDate1 = LocalDate。of(2019, 9, 10);複製程式碼
獲取年、月、日、星期幾
int year = localDate。getYear();int year1 = localDate。get(ChronoField。YEAR);Month month = localDate。getMonth();int month1 = localDate。get(ChronoField。MONTH_OF_YEAR);int day = localDate。getDayOfMonth();int day1 = localDate。get(ChronoField。DAY_OF_MONTH);DayOfWeek dayOfWeek = localDate。getDayOfWeek();int dayOfWeek1 = localDate。get(ChronoField。DAY_OF_WEEK);複製程式碼
LocalTime
只會獲取幾點幾分幾秒
建立LocalTime
LocalTime localTime = LocalTime。of(13, 51, 10); LocalTime localTime1 = LocalTime。now();複製程式碼
獲取時分秒
//獲取小時int hour = localTime。getHour();int hour1 = localTime。get(ChronoField。HOUR_OF_DAY);//獲取分int minute = localTime。getMinute();int minute1 = localTime。get(ChronoField。MINUTE_OF_HOUR);//獲取秒int second = localTime。getMinute();int second1 = localTime。get(ChronoField。SECOND_OF_MINUTE);複製程式碼
LocalDateTime
獲取年月日時分秒,等於LocalDate+LocalTime
建立LocalDateTime
LocalDateTime localDateTime = LocalDateTime。now();LocalDateTime localDateTime1 = LocalDateTime。of(2019, Month。SEPTEMBER, 10, 14, 46, 56);LocalDateTime localDateTime2 = LocalDateTime。of(localDate, localTime);LocalDateTime localDateTime3 = localDate。atTime(localTime);LocalDateTime localDateTime4 = localTime。atDate(localDate);複製程式碼
獲取LocalDate
LocalDate localDate2 = localDateTime。toLocalDate();複製程式碼
獲取LocalTime
LocalTime localTime2 = localDateTime。toLocalTime();複製程式碼
Instant
獲取秒數
建立Instant物件
Instant instant = Instant。now();複製程式碼
獲取秒數
long currentSecond = instant。getEpochSecond();複製程式碼
獲取毫秒數
long currentMilli = instant。toEpochMilli();複製程式碼
個人覺得如果只是為了獲取秒數或者毫秒數,使用System。currentTimeMillis()來得更為方便
修改LocalDate、LocalTime、LocalDateTime、Instant
LocalDate、LocalTime、LocalDateTime、Instant為
不可變物件
,修改這些物件物件會
返回一個副本
增加、減少年數、月數、天數等 以LocalDateTime為例
LocalDateTime localDateTime = LocalDateTime。of(2019, Month。SEPTEMBER, 10, 14, 46, 56);//增加一年localDateTime = localDateTime。plusYears(1);localDateTime = localDateTime。plus(1, ChronoUnit。YEARS);//減少一個月localDateTime = localDateTime。minusMonths(1);localDateTime = localDateTime。minus(1, ChronoUnit。MONTHS); 複製程式碼
透過with修改某些值
//修改年為2019localDateTime = localDateTime。withYear(2020);//修改為2022localDateTime = localDateTime。with(ChronoField。YEAR, 2022);複製程式碼
還可以修改月、日
時間計算
比如有些時候想知道這個月的最後一天是幾號、下個週末是幾號,透過提供的時間和日期API可以很快得到答案
LocalDate localDate = LocalDate。now();LocalDate localDate1 = localDate。with(firstDayOfYear());複製程式碼
比如透過firstDayOfYear()返回了當前日期的第一天日期,還有很多方法這裡不在舉例說明
格式化時間
LocalDate localDate = LocalDate。of(2019, 9, 10);String s1 = localDate。format(DateTimeFormatter。BASIC_ISO_DATE);String s2 = localDate。format(DateTimeFormatter。ISO_LOCAL_DATE);//自定義格式化DateTimeFormatter dateTimeFormatter = DateTimeFormatter。ofPattern(“dd/MM/yyyy”);String s3 = localDate。format(dateTimeFormatter);複製程式碼
DateTimeFormatter預設提供了多種格式化方式,如果預設提供的不能滿足要求,可以透過DateTimeFormatter的ofPattern方法建立自定義格式化方式
解析時間
LocalDate localDate1 = LocalDate。parse(“20190910”, DateTimeFormatter。BASIC_ISO_DATE);LocalDate localDate2 = LocalDate。parse(“2019-09-10”, DateTimeFormatter。ISO_LOCAL_DATE);複製程式碼
和SimpleDateFormat相比,DateTimeFormatter是執行緒安全的
小結
LocalDateTime:Date有的我都有,Date沒有的我也有,日期選擇請Pick Me
作者:何甜甜在嗎