Skip to content

Commit 98dc358

Browse files
committed
Update Java Notes
1 parent 5ab0f3a commit 98dc358

File tree

1 file changed

+101
-37
lines changed

1 file changed

+101
-37
lines changed

Java.md

Lines changed: 101 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,27 @@ G[float]
111111
G-->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
32563276
public 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-
//计算两个时间的间隔
33063327
public 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
1495714989
Thread 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 {
1744817513
CAS的全称是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

1745617521
CAS特点:
1745717522

17458-
* CAS 体现的是**无锁并发、无阻塞并发**
17459-
* 没有使用 synchronized,所以线程不会陷入阻塞,线程不需要频繁切换状态(上下文切换)
17523+
* CAS 体现的是**无锁并发、无阻塞并发**,没有使用 synchronized,所以线程不会陷入阻塞,线程不需要频繁切换状态(上下文切换,系统调用)
1746017524
* CAS 是基于乐观锁的思想
1746117525

1746217526
CAS缺点:

0 commit comments

Comments
 (0)