@@ -111,17 +111,27 @@ G[float]
111111G-->H[double]
112112```
113113
114+ ##### 上下转型
115+
114116* float 与 double:
115117
116- Java 不能隐式执行向下转型 ,因为这会使得精度降低
118+ Java 不能隐式执行**向下转型** ,因为这会使得精度降低
117119
118120 ```java
119121 //1.1字面量属于double类型,不能直接将1.1直接赋值给 float 变量,因为这是向下转型
120- float f = 1.1;
122+ float f = 1.1;//报错
121123 //1.1f 字面量才是 float 类型
122124 float f = 1.1f;
123125 ```
124126
127+ ```java
128+ float f1 = 1.234f;
129+ double d1 = f1;
130+
131+ double d2 = 1.23;
132+ float f2 = (float) d2;//向下转型需要强转
133+ ```
134+
125135* 隐式类型转换:
126136
127137 字面量 1 是 int 类型,它比 short 类型精度要高,因此不能隐式地将 int 类型向下转型为 short 类型
@@ -134,6 +144,16 @@ G-->H[double]
134144 s1 = (short) (s1 + 1);
135145 ```
136146
147+ ```java
148+ int i1 = 1245;
149+ long l1 = i1;
150+
151+ long l2 = 1234;
152+ int i2 = (int) l2;
153+ ```
154+
155+
156+
137157
138158
139159***
@@ -3237,20 +3257,20 @@ public static void main(String[] args){
32373257
32383258常用API:
32393259
3240- | 方法名 | 说明 |
3241- | ------------------------------------------------------------ | ----------------------------------------------------------- |
3242- | public int getYear() | 获取年 |
3243- | public int getMonthValue() | 获取月份(1-12) |
3244- | public int getDayOfMonth() | 获取月份中的第几天(1-31) |
3245- | public int getDayOfYear() | 获取一年中的第几天(1-366) |
3246- | public DayOfWeek getDayOfWeek() | 获取星期 |
3247- | public int getMinute() | 获取分钟 |
3248- | public int getHour() | 获取小时 |
3249- | public LocalDate toLocalDate () | 转换成为一个LocalDate对象(年月日) |
3250- | public LocalTime toLocalTime () | 转换成为一个LocalTime对象(时分秒) |
3251- | public String format (指定格式) | 把一个LocalDateTime格式化成为一个字符串 |
3252- | public LocalDateTime parse (准备解析的字符串, 解析格式) | 把一个日期字符串解析成为一个LocalDateTime对象 |
3253- | ** public static DateTimeFormatter ofPattern(String pattern)** | 使用指定的日期模板获取一个日期格式化器DateTimeFormatter对象 |
3260+ | 方法名 | 说明 |
3261+ | --------------------------------------------------------- | ----------------------------------------------------------- |
3262+ | public int getYear() | 获取年 |
3263+ | public int getMonthValue() | 获取月份(1-12) |
3264+ | public int getDayOfMonth() | 获取月份中的第几天(1-31) |
3265+ | public int getDayOfYear() | 获取一年中的第几天(1-366) |
3266+ | public DayOfWeek getDayOfWeek() | 获取星期 |
3267+ | public int getMinute() | 获取分钟 |
3268+ | public int getHour() | 获取小时 |
3269+ | public LocalDate toLocalDate() | 转换成为一个LocalDate对象(年月日) |
3270+ | public LocalTime toLocalTime() | 转换成为一个LocalTime对象(时分秒) |
3271+ | public String format(指定格式) | 把一个LocalDateTime格式化成为一个字符串 |
3272+ | public LocalDateTime parse(准备解析的字符串, 解析格式) | 把一个日期字符串解析成为一个LocalDateTime对象 |
3273+ | public static DateTimeFormatter ofPattern(String pattern) | 使用指定的日期模板获取一个日期格式化器DateTimeFormatter对象 |
32543274
32553275```java
32563276public class JDK8DateDemo2 {
@@ -3262,7 +3282,7 @@ public class JDK8DateDemo2 {
32623282 System.out.println(localDateTime);
32633283 DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
32643284 String s = localDateTime.format(pattern);
3265- LocalDateTime parse = LocalDateTime.parse(s, pattern);
3285+ LocalDateTime parse = LocalDateTime.parse(s, pattern);
32663286 }
32673287}
32683288```
@@ -3289,6 +3309,8 @@ public class JDK8DateDemo2 {
32893309
32903310**时间间隔**
32913311
3312+ Duration类API:
3313+
32923314| 方法名 | 说明 |
32933315| ------------------------------------------------ | -------------------- |
32943316| public static Period between(开始时间,结束时间) | 计算两个“时间"的间隔 |
@@ -3298,14 +3320,12 @@ public class JDK8DateDemo2 {
32983320| public long toTotalMonths() | 获取此期间的总月数 |
32993321| public static Durationbetween(开始时间,结束时间) | 计算两个“时间"的间隔 |
33003322| public long toSeconds() | 获得此时间间隔的秒 |
3301- | public int toMillis() | 获得此时间间隔的毫秒 |
3302- | public int toNanos() | 获得此时间间隔的纳秒 |
3323+ | public long toMillis() | 获得此时间间隔的毫秒 |
3324+ | public long toNanos() | 获得此时间间隔的纳秒 |
33033325
33043326```java
3305- //计算两个时间的间隔
33063327public class JDK8DateDemo9 {
33073328 public static void main(String[] args) {
3308- //public static Period between(开始时间,结束时间) 计算两个"时间"的间隔
33093329 LocalDate localDate1 = LocalDate.of(2020, 1, 1);
33103330 LocalDate localDate2 = LocalDate.of(2048, 12, 12);
33113331 Period period = Period.between(localDate1, localDate2);
@@ -6662,7 +6682,11 @@ public class FileDemo{
66626682
66636683
66646684
6665- #### API
6685+ ***
6686+
6687+
6688+
6689+ #### 常用API
66666690
66676691##### 常用方法
66686692
@@ -6722,7 +6746,7 @@ System.out.println(f.isDirectory()); // false
67226746
67236747
67246748
6725- ##### 创建和删除方法
6749+ ##### 创建删除
67266750
67276751`public boolean createNewFile()` : 当且仅当具有该名称的文件尚不存在时, 创建一个新的空文件。
67286752 (几乎不用的,因为以后文件都是自动创建的!)
@@ -6756,6 +6780,10 @@ public class FileDemo {
67566780
67576781
67586782
6783+ ***
6784+
6785+
6786+
67596787#### 遍历目录
67606788
67616789- `public String[] list()`:
@@ -6791,6 +6819,10 @@ public class FileDemo {
67916819
67926820
67936821
6822+ ***
6823+
6824+
6825+
67946826#### 文件搜索
67956827
67966828递归实现文件搜索(非规律递归)
@@ -6841,7 +6873,7 @@ public static void searchFiles(File dir , String fileName){
68416873
68426874
68436875
6844- ### 字符集
6876+ ### Character
68456877
68466878字符集:各个国家为自己国家的字符取的一套编号规则。
68476879 计算机的底层是不能直接存储字符的,只能存储二进制,010101。
@@ -6884,7 +6916,7 @@ public static void searchFiles(File dir , String fileName){
68846916
68856917
68866918
6887- ### IO流
6919+ ### IOStream
68886920
68896921#### 概述
68906922
@@ -11953,11 +11985,11 @@ Java语言提供了对象终止(finalization)机制来允许开发人员提
1195311985- 可复活的:对象的所有引用都被释放,但是对象有可能在finalize() 中复活
1195411986- 不可触及的:对象的 finalize() 被调用,并且没有复活,那么就会进入不可触及状态,不可触及的对象不可能被复活。因为**finalize()只会被调用一次**,等到这个对象再被标记为可回收时就必须回收
1195511987
11956- 注意:永远不要主动调用某个对象的finalize()方法,应该交给垃圾回收机制调用
11988+ 注意:永远不要主动调用某个对象的finalize()方法,应该交给垃圾回收机制调用,原因:
1195711989
11958- * finalize() 时可能会导致对象复活。
11990+ * finalize() 时可能会导致对象复活
1195911991* finalize() 方法的执行时间是没有保障的,它完全由GC线程决定,极端情况下,若不发生GC,则finalize()方法将没有执行机会。因为优先级比较低,即使主动调用该方法,也不会因此就直接进行回收
11960- * 一个糟糕的finalize() 会严重影响GC的性能。
11992+ * 一个糟糕的finalize() 会严重影响GC的性能
1196111993
1196211994
1196311995
@@ -14951,7 +14983,7 @@ System.out.println("unpark...");//和上一个unpark同时执行
1495114983
1495214984`public final void setDaemon(boolean on)`:如果是 true ,将此线程标记为守护线程
1495314985
14954- 线程启动前调用此方法 :
14986+ 线程**启动前**调用此方法 :
1495514987
1495614988```java
1495714989Thread t = new Thread() {
@@ -14961,15 +14993,15 @@ Thread t = new Thread() {
1496114993 }
1496214994};
1496314995// 设置该线程为守护线程
14964- t1 .setDaemon(true);
14965- t1 .start();
14996+ t .setDaemon(true);
14997+ t .start();
1496614998```
1496714999
1496815000用户线程:平常创建的普通线程
1496915001
1497015002守护线程:服务于用户线程,只要其它非守护线程运行结束了,即使守护线程代码没有执行完,也会强制结束
1497115003
14972- 面试 :当运行的线程都是守护线程,Java虚拟机将退出,因为普通线程执行完后,守护线程也不会继续运行下去
15004+ 说明 :当运行的线程都是守护线程,Java虚拟机将退出,因为普通线程执行完后,守护线程不会继续运行下去
1497315005
1497415006常见的守护线程:
1497515007
@@ -15728,9 +15760,42 @@ public class ThreadDead {
1572815760}
1572915761```
1573015762
15731- 定位死锁:
15763+ **定位死锁**:
15764+
15765+ * 检测死锁可以使用 jconsole工具,或者使用 jps 定位进程 id,再用 `jstack id`定位死锁
15766+
15767+ ```sh
15768+ "Thread-1" #12 prio=5 os_prio=0 tid=0x000000001eb69000 nid=0xd40 waiting formonitor entry [0x000000001f54f000]
15769+ java.lang.Thread.State: BLOCKED (on object monitor)
15770+ #省略
15771+ "Thread-1" #12 prio=5 os_prio=0 tid=0x000000001eb69000 nid=0xd40 waiting for monitor entry [0x000000001f54f000]
15772+ java.lang.Thread.State: BLOCKED (on object monitor)
15773+ #省略
15774+
15775+ Found one Java-level deadlock:
15776+ ===================================================
15777+ "Thread-1":
15778+ waiting to lock monitor 0x000000000361d378 (object 0x000000076b5bf1c0, a java.lang.Object),
15779+ which is held by "Thread-0"
15780+ "Thread-0":
15781+ waiting to lock monitor 0x000000000361e768 (object 0x000000076b5bf1d0, a java.lang.Object),
15782+ which is held by "Thread-1"
15783+
15784+ Java stack information for the threads listed above:
15785+ ===================================================
15786+ "Thread-1":
15787+ at thread.TestDeadLock.lambda$main$1(TestDeadLock.java:28)
15788+ - waiting to lock <0x000000076b5bf1c0> (a java.lang.Object)
15789+ - locked <0x000000076b5bf1d0> (a java.lang.Object)
15790+ at thread.TestDeadLock$$Lambda$2/883049899.run(Unknown Source)
15791+ at java.lang.Thread.run(Thread.java:745)
15792+ "Thread-0":
15793+ at thread.TestDeadLock.lambda$main$0(TestDeadLock.java:15)
15794+ - waiting to lock <0x000000076b5bf1d0> (a java.lang.Object)
15795+ - locked <0x000000076b5bf1c0> (a java.lang.Object)
15796+ at thread.TestDeadLock$$Lambda$1/495053715
15797+ ```
1573215798
15733- * 检测死锁可以使用 jconsole工具,或者使用 jps 定位进程 id,再用 jstack 定位死锁
1573415799* linux 下可以通过 top 先定位到CPU 占用高的 Java 进程,再利用 `top -Hp 进程id` 来定位是哪个线程,最后再用 jstack 排查
1573515800
1573615801避免死锁:避免死锁要注意加锁顺序
@@ -17448,15 +17513,14 @@ public final class Singleton {
1744817513CAS的全称是Compare-And-Swap,是**CPU并发原语**
1744917514
1745017515* CAS并发原语体现在Java语言中就是sun.misc.Unsafe类的各个方法,调用UnSafe类中的CAS方法,JVM会实现出CAS汇编指令,这是一种完全依赖于硬件的功能,通过它实现了原子操作
17451- * CAS是一种系统原语,原语属于操作系统范畴,是由若干条指令组成,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断 ,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致的问题,也就是说CAS是线程安全的
17516+ * CAS是一种系统原语,原语属于操作系统范畴,是由若干条指令组成,用于完成某个功能的一个过程,并且**原语的执行必须是连续的,执行过程中不允许被中断** ,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致的问题,也就是说CAS是线程安全的
1745217517* CAS 的底层是 lock cmpxchg 指令(X86 架构),在单核 CPU 和多核 CPU 下都能够保证比较交换的原子性。在多核状态下,某个核执行到带 lock 的指令时,CPU 会让总线锁住,当这个核把此指令执行完毕,再开启总线,这个过程不会被线程的调度机制所打断,保证了多个线程对内存操作的原子性
1745317518
1745417519作用:比较当前工作内存中的值和主物理内存中的值,如果相同则执行规定操作,否者继续比较直到主内存和工作内存的值一致为止
1745517520
1745617521CAS特点:
1745717522
17458- * CAS 体现的是**无锁并发、无阻塞并发**
17459- * 没有使用 synchronized,所以线程不会陷入阻塞,线程不需要频繁切换状态(上下文切换)
17523+ * CAS 体现的是**无锁并发、无阻塞并发**,没有使用 synchronized,所以线程不会陷入阻塞,线程不需要频繁切换状态(上下文切换,系统调用)
1746017524* CAS 是基于乐观锁的思想
1746117525
1746217526CAS缺点:
0 commit comments