(PSï¼æ«æ[é¦é¡µéé¢çäºç»´ç ](README.md)è¿ç¾¤ï¼å享æèªå·±å¨ççææ¯èµæç»å¤§å®¶ï¼å¸æå大家ä¸èµ·å¦ä¹ è¿æ¥ï¼)
ç®åè¿åªæ¯ä¹°äºææ°çç[ãæä½ç³»ç»å¯¼è®ºã](backend/bookRecommend?#ãæä½ç³»ç»å¯¼è®ºã),è¿æ²¡æå®å
¨çå®ï¼çå®ä¹åä¼ä»ç½ä¸çé¢ç»ä¸æ¾ä¸äºå®é
çé¢è¯é¢ï¼ç¶åèªå·±éè¿ç¿»ä¹¦æ¥èµæï¼åé¢è¯é¢è§£çã
#### [1.è¿ç¨ä¸çº¿ç¨çåºå«æ¯ä»ä¹ï¼](#è¿ç¨ä¸çº¿ç¨çåºå«æ¯ä»ä¹ï¼)
#### [2.è¿ç¨é´å¦ä½éä¿¡ï¼](#è¿ç¨é´å¦ä½éä¿¡ï¼)
#### [3.Javaä¸å便åªäºåæ³ï¼](#Javaä¸å便åªäºåæ³ï¼)
#### [4.Javaä¸åå»ºçº¿ç¨æåªäºæ¹å¼?](#Javaä¸åå»ºçº¿ç¨æåªäºæ¹å¼?)
#### [5.å¦ä½è§£å³åºååæ¶å¯ä»¥å建åºåä¾å¯¹è±¡çé®é¢?](#å¦ä½è§£å³åºååæ¶å¯ä»¥å建åºåä¾å¯¹è±¡çé®é¢?)
#### [6.æ²è§éåä¹è§éæ¯ä»ä¹ï¼](#æ²è§éåä¹è§éæ¯ä»ä¹ï¼)
#### [7.volatileå
³é®åæä»ä¹ç¨ï¼æä¹çè§£å¯è§æ§ï¼ä¸è¬ä»ä¹åºæ¯å»ç¨å¯è§æ§ï¼](#volatileå
³é®åæä»ä¹ç¨ï¼æä¹çè§£å¯è§æ§ï¼ä¸è¬ä»ä¹åºæ¯å»ç¨å¯è§æ§ï¼)
#### [8.sychronizeçå®ç°åçæ¯æä¹æ ·çï¼](#sychronizeçå®ç°åçæ¯æä¹æ ·çï¼)
### è¿ç¨ä¸çº¿ç¨çåºå«æ¯ä»ä¹ï¼
è¿ç¨æ¯è®¡ç®æºä¸å·²è¿è¡ç¨åºçå®ä½ï¼è¿ç¨æ¯æä½ç³»ç»èµæºåé
çæå°åä½ï¼æ¥æç¬ç«çå°å空é´ï¼å
·å¤ç¬ç«æ§ï¼å¨ææ§ï¼å¹¶åæ§ã
çº¿ç¨æ¯CPUè°åº¦åæ§è¡çæå°åä½ï¼çº¿ç¨å
±äº«åä¸è¿ç¨çèµæºï¼ä¸ä¸æåæ¢ææ¬æ´å ä½ï¼çº¿ç¨é´çéä¿¡ææ¬ä¹ä¼ä½ä¸äºã
#### ç¬ç«æ§
Linuxç³»ç»ä¼ç»æ¯ä¸ªè¿ç¨åé
4Gçèæå°å空é´(0å°3Gæ¯Userå°å空é´ï¼3å°4Gé¨åæ¯kernelå°å空é´)ï¼è¿ç¨å
·å¤ç§æçå°å空é´ï¼æªç»å
许ï¼ä¸ä¸ªç¨æ·è¿ç¨ä¸è½è®¿é®å
¶ä»è¿ç¨çå°å空é´ã
#### 卿æ§
ç¨åºæ¯ä¸ä¸ªéæçæä»¤éåï¼èè¿ç¨æ¯æ£å¨æä½ç³»ç»ä¸è¿è¡çæä»¤éåï¼è¿ç¨æèªå·±ççå½å¨æååç§ä¸åçç¶æãï¼äºææ¨¡åä¸è¬æçæ¯æ°å»ºæï¼å建ä¸ä¸ªè¿ç¨ï¼ï¼å°±ç»ªæï¼å·²ç»è·åå°èµæºï¼åå¤å¥½äºï¼è¿å
¥è¿è¡éåï¼ä¸æ¦è·å¾æ¶é´çå¯ä»¥ç«å³æ§è¡ï¼ï¼é»å¡æï¼è¿è¡è¿ç¨ä¸çå¾
è·åå
¶ä»èµæºï¼I/O请æ±çï¼ï¼ç»æ¢æï¼è¿ç¨è¢«ææ»äºï¼ï¼ã
#### å¹¶åæ§
å¤ä¸ªè¿ç¨å¯ä»¥å¨CPUä¸å¹¶åæ§è¡ã
çº¿ç¨æ¯ç¬ç«è¿è¡åè°åº¦çæå°åä½ï¼çº¿ç¨ä¼å
±äº«è¿ç¨çèæç©ºé´ï¼ä¸ä¸ªè¿ç¨ä¼å¯¹åºå¤ä¸ªçº¿ç¨ãå¨Javaä¸ï¼çº¿ç¨æ¥æèªå·±ç§æçç¨åºè®¡æ°å¨ï¼èææºæ ï¼æ¬å°æ¹æ³æ ã
#### PS:èæå
å
èæå
忝ä¸ç§é»è¾ä¸æ©å
ç©çå
åçææ¯ãåºæ¬ææ³æ¯ç¨è½¯ãç¡¬ä»¶ææ¯æå
åä¸å¤åè¿ä¸¤çº§åå¨å¨å½åä¸çº§åå¨å¨æ¥ç¨ãèæå
åææ¯çå®ç°å©ç¨äºèªå¨è¦çåäº¤æ¢ææ¯ãç®åç说就æ¯å°ç¡¬ççä¸é¨åä½ä¸ºå
åæ¥ä½¿ç¨ã
#### PS:èæå°å空é´
æ¯ä¸ªè¿ç¨æ4Gçå°å空é´ï¼å¨è¿è¡ç¨åºæ¶ï¼åªæä¸é¨åæ°æ®æ¯çæ£å è½½å°å
åä¸çï¼å
å管çåå
å°èæå°å转æ¢ä¸ºç©çå°åï¼å¦æå
åä¸ä¸åå¨è¿é¨åæ°æ®ï¼é£ä¹ä¼ä½¿ç¨é¡µé¢ç½®æ¢æ¹æ³ï¼å°å
å页置æ¢åºæ¥ï¼ç¶åå°å¤åä¸çæ°æ®å å
¥å°å
åä¸ï¼ä½¿å¾ç¨åºæ£å¸¸è¿è¡ã
### è¿ç¨é´å¦ä½éä¿¡ï¼
è¿ç¨é´éä¿¡çæ¹å¼ä¸»è¦æç®¡éï¼
#### 管é
è°ç¨pipe彿°å¨å
åä¸å¼è¾ä¸åç¼å²åºï¼ç®¡éååå·¥çï¼å³æ°æ®åªè½å¨ä¸ä¸ªæ¹å䏿µå¨ï¼ï¼å
·æåºå®ç读端åå端ï¼è°ç¨
```
#include
int pipe(int pipefd[2]);
```
### Javaä¸åå»ºçº¿ç¨æåªäºæ¹å¼ï¼
æåºæ¬çæ¹å¼å°±æ¯ç»§æ¿
#### 第ä¸ç§ ç»§æ¿Threadç±»ï¼éåRunæ¹æ³
è¿ç§æ¹æ³å°±æ¯éè¿èªå®ä¹CustomThread类继æ¿Threadç±»ï¼éårun()æ¹æ³ï¼ç¶åå建CustomThreadç对象ï¼ç¶åè°ç¨start()æ¹æ³ï¼JVMä¼å建åºä¸ä¸ªæ°çº¿ç¨ï¼å¹¶ä¸ä¸ºçº¿ç¨åå»ºæ¹æ³è°ç¨æ åç¨åºè®¡æ°å¨ï¼æ¤æ¶çº¿ç¨å¤äºå°±ç»ªç¶æï¼å½çº¿ç¨è·åCPUæ¶é´çåï¼çº¿ç¨ä¼è¿å
¥å°è¿è¡ç¶æï¼ä¼å»è°ç¨run()æ¹æ³ãå¹¶ä¸å建CustomThreadç±»ç对象ç线ç¨(è¿éçä¾å䏿¯ä¸»çº¿ç¨)ä¸è°ç¨run()æ¹æ³ç线ç¨ä¹é´æ¯å¹¶åçï¼ä¹å°±æ¯å¨æ§è¡run()æ¹æ³æ¶ï¼ä¸»çº¿ç¨å¯ä»¥å»æ§è¡å
¶ä»æä½ã
```java
class CustomThread extends Thread {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"线ç¨è°ç¨äºmainæ¹æ³");
for (int i = 0; i < 10; i++) {
if (i == 1) {
CustomThread customThread = new CustomThread();
customThread.start();
System.out.println(Thread.currentThread().getName()+"线ç¨--iæ¯"+i);
}
}
System.out.println("main()æ¹æ³æ§è¡å®æ¯ï¼");
}
void run() {
System.out.println(Thread.currentThread().getName()+"线ç¨è°ç¨äºrun()æ¹æ³");
for (int j = 0; j < 20; j++) {
System.out.println(Thread.currentThread().getName()+"线ç¨--jæ¯"+j);
}
System.out.println("run()æ¹æ³æ§è¡å®æ¯ï¼");
}
}
```
è¾åºç»æå¦ä¸ï¼
```
main线ç¨è°ç¨äºmainæ¹æ³
Thread-0线ç¨è°ç¨äºrun()æ¹æ³
Thread-0线ç¨--jæ¯0
Thread-0线ç¨--jæ¯1
Thread-0线ç¨--jæ¯2
Thread-0线ç¨--jæ¯3
Thread-0线ç¨--jæ¯4
Thread-0线ç¨--jæ¯5
Thread-0线ç¨--jæ¯6
Thread-0线ç¨--jæ¯7
Thread-0线ç¨--jæ¯8
Thread-0线ç¨--jæ¯9
Thread-0线ç¨--jæ¯10
Thread-0线ç¨--jæ¯11
Thread-0线ç¨--jæ¯12
Thread-0线ç¨--jæ¯13
Thread-0线ç¨--jæ¯14
main线ç¨--iæ¯1
Thread-0线ç¨--jæ¯15
Thread-0线ç¨--jæ¯16
Thread-0线ç¨--jæ¯17
Thread-0线ç¨--jæ¯18
Thread-0线ç¨--jæ¯19
run()æ¹æ³æ§è¡å®æ¯ï¼
main()æ¹æ³æ§è¡å®æ¯ï¼
```
å¯ä»¥çå°å¨å建ä¸ä¸ªCustomThread对象ï¼è°ç¨start()æ¹æ³åï¼Thread-0è°ç¨äºrunæ¹æ³ï¼è¿è¡for循ç¯ï¼å¯¹jè¿è¡æå°ï¼ä¸æ¤åæ¶ï¼main线ç¨å¹¶æ²¡æè¢«é»å¡ï¼èæ¯ç»§ç»æ§è¡for循ç¯ï¼å¯¹iè¿è¡æå°ã
##### æ§è¡åç
é¦å
æä»¬å¯ä»¥æ¥ççstartçæºç ï¼é¦å
ä¼å¤æthreadStatusæ¯å¦ä¸º0ï¼å¦æä¸ä¸º0伿åºå¼å¸¸ãç¶åä¼å°å½å对象添å å°çº¿ç¨ç»ï¼æåè°ç¨start0æ¹æ³ï¼å 为æ¯nativeæ¹æ³ï¼çä¸å°æºç ï¼æ ¹æ®ä¸é¢çæ§è¡ç»ææ¥çï¼JVMæ°å»ºäºä¸ä¸ªçº¿ç¨è°ç¨äºrunæ¹æ³ã
```java
private native void start0();
public synchronized void start() {
//夿å½åThread对象æ¯å¦æ¯æ°å»ºæï¼å¦åæåºå¼å¸¸
if (threadStatus != 0)
throw new IllegalThreadStateException();
//å°å½å对象添å å°çº¿ç¨ç»
group.add(this);
boolean started = false;
try {
start0();//è¿æ¯ä¸ä¸ªnativeæ¹æ³ï¼è°ç¨åJVM伿°å»ºä¸ä¸ªçº¿ç¨æ¥è°ç¨runæ¹æ³
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
```
æ©å±é®é¢ï¼å¤æ¬¡è°ç¨Thread对象çstart()æ¹æ³ä¼æä¹æ ·ï¼
伿åºIllegalThreadStateExceptionå¼å¸¸ãå
¶å®å¨Thread#start()æ¹æ³éé¢ççæ³¨é䏿æå°ï¼å¤æ¬¡è°ç¨start()æ¹æ³æ¯éæ³çï¼æä»¥å¨ä¸é¢çstart()æ¹æ³æºç ä¸ä¸å¼å§å°±æ¯å¯¹threadStatusè¿è¡å¤æï¼ä¸ä¸º0就伿åºIllegalThreadStateExceptionå¼å¸¸ã

##### 注æäºé¡¹ï¼
start()æ¹æ³ä¸å¤æthreadStatusæ¯å¦ä¸º0ï¼æ¯å¤æå½åçº¿ç¨æ¯å¦æ°å»ºæï¼0æ¯ä»£è¡¨æ°å»ºæ(ä¸å¾ä¸çæºç 注éé颿æå°)ï¼è䏿¯å°±ç»ªæï¼å 为Javaä¸ï¼å°±ç»ªæåè¿è¡ææ¯åå¹¶å¨ä¸èµ·çï¼ï¼Threadçstate为RUNNABLEæ¶(ä¹å°±æ¯threadStatus为4æ¶)ï¼ä»£è¡¨çº¿ç¨ä¸ºå°±ç»ªææè¿è¡æï¼ãæ§è¡start()æ¹æ³ç线ç¨è¿ä¸æ¯JVMæ°å»ºç线ç¨ï¼æä»¥ä¸æ¯å°±ç»ªæãæä¸äºææ¯æç« æè¿éå¼éäºï¼ä¾å¦è¿ä¸ç¯[ãæ·±å
¥æµ
åºçº¿ç¨Threadç±»çstart()æ¹æ³årun()æ¹æ³ã](https://juejin.im/post/5b09274af265da0de25759d5)

##### æ»ç»
è¿ç§æ¹å¼ç缺ç¹å¾ææ¾ï¼å°±æ¯éè¦ç»§æ¿Threadç±»ï¼èä¸å®é
䏿们çéæ±å¯è½ä»
ä»
æ¯å¸ææäºæä½è¢«ä¸ä¸ªå
¶ä»ççº¿ç¨æ¥æ§è¡ï¼æä»¥æäºç¬¬äºç§æ¹æ³ã
#### 第äºç§ å®ç°Runnableæ¥å£
è¿ç§æ¹å¼å°±æ¯å建ä¸ä¸ªç±»Targetï¼å®ç°Runnableæ¥å£çRunæ¹æ³ï¼ç¶åå°Targetç±»çå®ä¾å¯¹è±¡ä½ä¸ºThreadçæé å¨å
¥åtargetï¼å®é
ç线ç¨å¯¹è±¡è¿æ¯Threadå®ä¾ï¼åªä¸è¿çº¿ç¨Threadä¸çº¿ç¨æ§è¡ä½ï¼Targetç±»çrunæ¹æ³ï¼å离äºï¼è¦å度æ´ä½ä¸äºã
```java
class ThreadTarget implements Runnable {
void run() {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºrunæ¹æ³");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºmainæ¹æ³");
ThreadTarget target = new ThreadTarget();
Thread thread = new Thread(target);
thread.start();
}
}
```
è¾åºç»æå¦ä¸ï¼

##### åç
乿以æè¿ç§å®ç°æ¹æ³ï¼æ¯å 为Threadç±»çrunæ¹æ³ä¸ä¼å¤ææååétargetæ¯å¦ä¸ºç©ºï¼ä¸ä¸ºç©ºå°±ä¼è°ç¨targetç±»çrunæ¹æ³ã
```java
private Runnable target;
public void run() {
if (target != null) {
target.run();
}
}
```
##### å¦å¤ä¸ç§åæ³
è¿ç§å®ç°æ¹å¼ä¹æå
¶ä»çåæ³ï¼å¯ä»¥ä¸å建Targetç±»ã
##### å¿åå
é¨ç±»
å¯ä»¥ä¸å建Targetç±»ï¼å¯ä»¥ä½¿ç¨å¿åå
é¨ç±»çæ¹å¼æ¥å®ç°ï¼å æ¤ä¸é¢ç代ç ä¹å¯ä»¥æä»¥ä¸æ¹å¼åï¼
```java
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºrunæ¹æ³");
}
});
thread.start();
```
##### Lamda表达å¼
å¨Java8ä¹åï¼ä½¿ç¨äº@FunctionalInterface注解æ¥ä¿®é¥°Runnableæ¥å£ï¼è¡¨æRunnableæ¥å£æ¯ä¸ä¸ªå½æ°å¼æ¥å£ï¼æä¸åªæä¸ä¸ªæ½è±¡æ¹æ³ï¼å¯ä»¥Lambdaæ¹å¼æ¥å建Runnableå¯¹è±¡ï¼æ¯ä½¿ç¨å¿åç±»çæ¹å¼æ´å ç®æ´ä¸äºã
```java
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
```
å æ¤ä¸é¢ç代ç ä¹å¯ä»¥æä»¥ä¸æ¹å¼åï¼
```java
Thread thread = new Thread(()->{
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºrunæ¹æ³");
})
thread.start()
```
##### æ»ç»
è¿ç§åæ³ä¸ç¨ç»§æ¿Threadï¼ä½æ¯åæ ·ä¹æç¼ºç¹ï¼å°±æ¯çº¿ç¨æ¹æ³ä½(ä¹å°±æ¯runæ¹æ³)ä¸è½è®¾ç½®è¿åå¼ã
#### 第ä¸ç§ å®ç°Callableæ¥å£
å建ä¸ä¸ªç±»CallableTargetï¼å®ç°Callableæ¥å£ï¼å®ç°å¸¦æè¿åå¼çcall()æ¹æ³ï¼ä»¥CallableTargetå®ä¾å¯¹è±¡ä½ä¸ºå建FutureTask对象çåæ°ï¼FutureTaskå®ç°äºRunnableFutureæ¥å£ï¼èRunnableFutureæ¥å£ç»§æ¿äºRunnable, Futureæ¥å£ï¼æä»¥FutureTask对象å¯ä»¥ä½ä¸ºå建Thread对象çå
¥åï¼å建Thread对象ï¼ç¶åè°ç¨startæ¹æ³ã
```java
public class CallableTarget implements Callable {
public Integer call() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºcallæ¹æ³");
Thread.sleep(5000);
return 1;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºmainæ¹æ³");
CallableTarget callableTarget = new CallableTarget();
FutureTask task = new FutureTask(callableTarget);
Thread thread = new Thread(task);
thread.start();
Integer result = task.get();//å½å线ç¨ä¼é»å¡ï¼ä¸ç´çå°ç»æè¿åã
System.out.println("æ§è¡å®æ¯ï¼æå°result="+result);
System.out.println("æ§è¡å®æ¯");
}
}
```
Callableæ¥å£çæºç
```java
@FunctionalInterface
public interface Callable {
V call() throws Exception;
}
```
RunnableFutureæ¥å£çæºç
```java
public interface RunnableFuture extends Runnable, Future {
void run();
}
```
### Javaä¸å便åªäºåæ³ï¼
æ£ç¡®å¹¶ä¸å¯ä»¥åå°å»¶è¿å è½½çåæ³å
¶å®å°±æ¯ä¸ç§ï¼
使ç¨volatile修饰åéå¹¶ä¸åéæ ¡éªçåæ³ã
使ç¨éæå
é¨ç±»æ¥å®ç°ï¼ç±»Aæä¸ä¸ªéæå
é¨ç±»Bï¼ç±»Bæä¸ä¸ªéæåéinstanceï¼ç±»AçgetInstance()æ¹æ³ä¼è¿åç±»Bçéæåéinstanceï¼å ä¸ºåªæè°ç¨getInstance()æ¹æ³æ¶æä¼å è½½éæå
é¨ç±»Bï¼è¿ç§åæ³ç¼ºç¹æ¯ä¸è½ä¼ åãï¼
ä½¿ç¨æä¸¾æ¥å®ç°ï¼ï¼
#### 第1ç§ ä¸å éï¼è£¸å¥åæ³ï¼
å¤çº¿ç¨æ§è¡æ¶ï¼å¯è½ä¼å¨instance宿åå§åä¹åï¼å
¶ä»çº¿æ§çº¿ç¨å¤æinstance为nullï¼ä»è乿§è¡ç¬¬äºæ¥ç代ç ï¼å¯¼è´åå§åè¦çã
```java
public class UnsafeLazyInitialization {
private static Instance instance;
public static Instance getInstance() {
if (instance == null) //1
instance = new Instance(); //2
}
return instance;
}
```
#### 第2ç§-å¯¹æ¹æ³å sychronizeé(ä¿ç§°çææ±æ¨¡å¼)
åå§å宿以åï¼æ¯æ¬¡è°ç¨getInstance()æ¹æ³é½éè¦è·å忥éï¼å¯¼è´ä¸å¿
è¦çå¼éã
```java
public class Singleton {
private static Singleton instance;
public synchronized static Singleton getInstance() {
if (instance == null)
instance = new Instance();
return instance;
}
}
```
#### 第3ç§-使ç¨éæåé(ä¿ç§°çé¥¿æ±æ¨¡å¼)
```
public class Singleton {
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
```
è¿ç§æ¹æ³æ¯ç¼ºç¹å¨äºä¸è½åå°å»¶æ¶å è½½ï¼å¨ç¬¬ä¸æ¬¡è°ç¨getInstance()æ¹æ³ä¹åï¼å¦æSingleton类被使ç¨å°ï¼é£ä¹å°±ä¼å¯¹instanceåéåå§åã
#### 第4ç§-使ç¨å鿣æ¥éå®
代ç å¦ä¸ï¼
```java
public class Singleton {
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) { //å鿣æ¥åå¨çæä¹å¨äºå¯è½ä¼æå¤ä¸ªçº¿ç¨è¿å
¥ç¬¬ä¸ä¸ªå¤æï¼ç¶åç«äºåæ¥éï¼çº¿ç¨Aå¾å°äºåæ¥éï¼å建äºä¸ä¸ªSingletonå®ä¾ï¼èµå¼ç»instanceï¼ç¶å鿾忥éï¼æ¤æ¶çº¿ç¨Bè·å¾åæ¥éï¼åä¼å建ä¸ä¸ªSingletonå®ä¾ï¼é æåå§åè¦çã
instance = new Singleton();
}
}
}
return instance;
}
}
```
instance = new Singleton();
è¿å¥ä»£ç 卿§è¡æ¶ä¼å解为ä¸ä¸ªæ¥éª¤ï¼
1.为对象åé
å
å空é´ã
2.æ§è¡åå§åç代ç ã
3.å°åé
好çå
åå°å设置ç»instanceå¼ç¨ã
使¯ç¼è¯å¨ä¼å¯¹æä»¤è¿è¡éæåºï¼åªè½ä¿è¯åçº¿ç¨æ§è¡æ¶ç»æä¸ä¼ååï¼ä¹å°±æ¯å¯è½ç¬¬3æ¥ä¼å¨ç¬¬2æ¥ä¹åæ§è¡ï¼æä¸ªçº¿ç¨Aå好æ§è¡å®ç¬¬3æ¥ï¼æ£å¨æ§è¡ç¬¬2æ¥æ¶ï¼æ¤æ¶å¦ææå
¶ä»çº¿ç¨Bè¿å
¥if (instance == null)夿ï¼ä¼åç°instanceä¸ä¸ºnullï¼ç¶åå°instanceè¿åï¼ä½æ¯å®é
ä¸instanceè¿æ²¡æå®æåå§åï¼çº¿ç¨Bä¼è®¿é®å°ä¸ä¸ªæªåå§å宿çinstance对象ã
#### 第5ç§ åºäº volatile çå鿣æ¥éå®çè§£å³æ¹æ¡
代ç å¦ä¸ï¼
```java
public class Singleton {
private volatile static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null)//å鿣æ¥åå¨çæä¹å¨äºå¯è½ä¼æå¤ä¸ªçº¿ç¨è¿å
¥ç¬¬ä¸ä¸ªå¤æï¼ç¶åç«äºåæ¥éï¼çº¿ç¨Aå¾å°äºåæ¥éï¼å建äºä¸ä¸ªSingletonå®ä¾ï¼èµå¼ç»instanceï¼ç¶å鿾忥éï¼æ¤æ¶çº¿ç¨Bè·å¾åæ¥éï¼åä¼å建ä¸ä¸ªSingletonå®ä¾ï¼é æåå§åè¦çã
instance = new Singleton();
}
}
return instance;
}
}
```
volatileå¯ä»¥ä¿è¯åéçå
åå¯è§æ§å鲿¢æä»¤éæã
volatile修饰çåéå¨ç¼è¯åï¼ä¼å¤åºä¸ä¸ªlockåç¼æä»¤ï¼lockåç¼æä»¤ç¸å½äºä¸ä¸ªå
åå±éï¼å
åæ
æ ï¼ï¼æä¸ä¸ªä½ç¨ï¼
* ç¡®ä¿æä»¤éæåºæ¶ï¼å
åå±éåçæä»¤ä¸ä¼æå°åé¢å»ï¼å
åå±éåçæä»¤ä¸ä¼æå°åé¢å»ã
* 强å¶å¯¹åéå¨çº¿ç¨å·¥ä½å
åä¸çä¿®æ¹æä½ç«å³åå
¥å°ç©çå
åã
* 妿æ¯åæä½ï¼ä¼å¯¼è´å
¶ä»CPUä¸å¯¹è¿ä¸ªåéçç¼å失æï¼å¼ºå¶å
¶ä»CPUä¸ç线ç¨å¨è·ååéæ¶ä»ç©çå
åä¸è·åæ´æ°åçå¼ã
æä»¥ä½¿ç¨volatile修饰åä¸ä¼åºç°ç¬¬3ç§åæ³ä¸ç±äºæä»¤éæåºå¯¼è´çé®é¢ã
#### 第6ç§ - 使ç¨éæå
é¨ç±»æ¥å®ç°
```java
private static class Signleton {
private static Signleton instance = new Signleton();
}
public static Signleton getInstance() {
return Signleton.instance ; // è¿éå°å¯¼è´ Signleton 类被åå§å
}
```
å 为JVMåºå±éè¿å éå®ç°ï¼ä¿è¯ä¸ä¸ªç±»åªä¼è¢«å è½½ä¸æ¬¡ï¼å¤ä¸ªçº¿ç¨å¨å¯¹ç±»è¿è¡åå§åæ¶ï¼åªæä¸ä¸ªçº¿ç¨ä¼è·å¾éï¼ç¶å对类è¿è¡åå§åï¼å
¶ä»çº¿ç¨ä¼é»å¡çå¾
ãæä»¥å¯ä»¥ä½¿ç¨ä¸é¢çä»£ç æ¥ä¿è¯instanceåªä¼è¢«åå§å䏿¬¡ï¼è¿ç§åæ³çé®é¢å¨äºå建å便¶ä¸è½ä¼ åã
#### 7.ä½¿ç¨æä¸¾æ¥å®ç°åä¾
```java
public enum Singleton {
//æ¯ä¸ªå
ç´ å°±æ¯ä¸ä¸ªåä¾
INSTANCE;
//èªå®ä¹çä¸äºæ¹æ³
public void method(){}
}
```
è¿ç§åæ³æ¯è¾ç®æ´ï¼ä½æ¯ä¸å¤ªä¾¿äºé
读åçè§£ï¼æä»¥å®é
å¼åä¸åºç¨å¾æ¯è¾å°ï¼èä¸ç±äºæä¸¾ç±»æ¯ä¸è½éè¿åå°æ¥å建å®ä¾ç(åå°æ¹æ³newInstanceä¸å¤ææ¯æä¸¾ç±»åï¼ä¼æåºIllegalArgumentExceptionå¼å¸¸)ï¼æä»¥å¯ä»¥é²æ¢åå°ãèä¸ç±äºæä¸¾ç±»åçååºå忝éè¿java.lang.EnumçvalueOfæ¹æ³æ¥å®ç°çï¼ä¸è½èªå®ä¹åºååæ¹æ³ï¼å¯ä»¥é²æ¢éè¿åºå忥å建å¤ä¸ªåä¾ã
### å¦ä½è§£å³åºååæ¶å¯ä»¥å建åºåä¾å¯¹è±¡çé®é¢?
妿å°åä¾å¯¹è±¡åºååæåèåºååï¼ç¶ååååºåæå¯¹è±¡ï¼é£ä¹å°±å¯ä»¥å建åºä¸ä¸ªæ°çåä¾å¯¹è±¡ï¼ä»è导è´åä¾ä¸å¯ä¸ï¼é¿å
åçè¿ç§æ
åµçè§£å³æ¹æ¡æ¯å¨åä¾ç±»ä¸å®ç°readResolve()æ¹æ³ã
```java
public class Singleton implements java.io.Serializable {
private Object readResolve() {
return INSTANCE;
}
}
```
éè¿å®ç°readResolveæ¹æ³ï¼ObjectInputStreamå®ä¾å¯¹è±¡å¨è°ç¨readObject()æ¹æ³è¿è¡ååºååæ¶ï¼å°±ä¼å¤æç¸åºçç±»æ¯å¦å®ç°äºreadResolve()æ¹æ³ï¼å¦æå®ç°äºï¼å°±ä¼è°ç¨readResolve()æ¹æ³è¿åä¸ä¸ªå¯¹è±¡ä½ä¸ºååºååçç»æï¼è䏿¯å»å建ä¸ä¸ªæ°ç对象ã
### æ²è§éåä¹è§éæ¯ä»ä¹ï¼
##### æ²è§é
å°±æ¯åå®å¨æ¯æ¬¡åæ°æ®çæ¶åä¼ä¿®æ¹è¿ä¸ªæ°æ®ï¼æä»¥å¨åæ°æ®çæ¶åå°±ä¼è¿è¡å éï¼è¿æ ·å
¶ä»è°ç¨è
å°±ä¸è½åæ°æ®ï¼é»å¡çå¾
ï¼ä¸ç´å°è·åå°éãJavaä¸ç忥ésychronizedåReentrantLockå°±æ¯æ²è§éææ³çå®ç°ã
##### ä¹è§é
å°±æ¯åå®å¨æ¯æ¬¡åæ°æ®æ¶ä¸ä¼ä¿®æ¹è¿ä¸ªæ°æ®ï¼æä»¥å¨åæ°æ®çæ¶åä¸ä¼å éï¼åªæå¨çæ£ä¿®æ¹æ°æ®æ¶æå éãJavaä¸çatomicåååé类就æ¯ä¹è§éçå®ç°ã
##### åºå«
##### æ²è§ééåå¤åçåºæ¯ï¼
ä¹è§ééåå¤è¯»çåºæ¯ï¼è¿æ ·åªæè¯»åå²çªä¼åççæ¯è¾å°ï¼åå°å éçæ§è½å¼éã使¯å¦ææ¯å¤åçåºæ¯ï¼è¿æ ·ä¼å¯¼è´ä¸å±åºç¨ä¸ç´éè¯ï¼å¢å æ§è½å¼éã
### ä¹è§éçå®ç°
#### çæ¬å·æºå¶
使ç¨çæ¬å·æ¥å®ç°ï¼å¯¹æ°æ®å ä¸ä¸ä¸ªçæ¬å·ï¼ä»£è¡¨ä¿®æ¹æ¬¡æ°ï¼æ¯æ¬¡ä¿®æ¹å+1ï¼ä¿®æ¹æ°æ®æ¶å¤ææ°æ®ççæ¬å·è·ä¹ååçæ¯å¦ä¸è´ï¼ä¸è´æä¿®æ¹ï¼ä¸ä¸è´å°±éè¯ï¼ç´å°æ´æ°æåã
#### CASæä½
å°±æ¯å¨æ´æ°æ°æ®æ¶ä¼ä¼ å
¥ä¹ååçå¼ï¼å¨å
åä¸å¤æå½åå
åä¸çå¼è·ä¹åç弿¯å¦ä¸è´ï¼ä¸è´åæ´æ°ï¼ï¼æ¯è¾åæ´æ°é½æ¯å¨ä¸ä¸ªååæä½ä¸ï¼ã
##### ABAé®é¢
使¯æ²¡æ³è§£å³ABAçé®é¢ï¼å°±æ¯å
¶ä»è°ç¨æ¹å¯¹æ°æ®ä¿®æ¹æå
¶ä»å¼ååæ¹å忥çå¼ãAtomicStampedReferenceçcompareAndSetä¼å
å¤æå¯¹è±¡çå¼ç¨æ¯å¦ç¸åï¼ç¸åæè¿è¡CASæ´æ°ãå®ç°åçä¸»è¦æ¯AtomicStampedReferenceä¼ä¿åä¹å对象ççå¼ç¨ï¼åä¸ä¸ªä¿®æ¹çæ¬å·ï¼åªæå½å¼ç¨åçæ¬å·é½ç¸ççæ
åµä¸ï¼æä¼è¿è¡CASæ´æ°æä½ã
##### å¾ªç¯æ¶é´é¿å¼é大
èªæCASæä½å¦æä¸æåå°±ä¸ç´å¾ªç¯æ§è¡ç´å°æåï¼å¦æé¿æ¶é´ä¸æåï¼ä¼ç»CPU带æ¥éå¸¸å¤§çæ§è¡å¼é
##### CAS åªå¯¹å个å
±äº«åéææ
å¤ä¸ªåéæ¾å¨ä¸ä¸ªå¯¹è±¡éæ¥è¿è¡ CAS æä½.æä»¥æä»¬å¯ä»¥ä½¿ç¨éæè
å©ç¨`AtomicReferenceç±»`æå¤ä¸ªå
±äº«åéåå¹¶æä¸ä¸ªå
±äº«å鿥æä½
#### Javaçååç±»
ååç±»ä¸å
±æä»¥ä¸åç§
- 1.åºæ¬ç±»å: AtomicInteger, AtomicLong, AtomicBoolean ;
- 2.æ°ç»ç±»å: AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray ;
- 3.å¼ç¨ç±»å: AtomicReference, AtomicStampedRerence, AtomicMarkableReference ;
- 4.对象ç屿§ä¿®æ¹ç±»å: AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater ã
##### AtomicInteger
ä¸»è¦æ¯å¯¹Integerçå°è£
ï¼æä¾äºä¸äºååæ§çæä½ï¼å ä¸ºå¦ææ¯ä½¿ç¨Integeræ¥å®æi=i+1;æä½ï¼å¨å
å䏿¯ä¸ä¸ªæ¥éª¤ï¼å
å°ä»å
åä¸ååºiï¼æ¾å°å¯åå¨ä¸ï¼ç¶åå°å¯åå¨ä¸çå¼ä¸1ç¸å ï¼ç¶åå°ç»æåå
¥å
åï¼ä¸å
±æ¯ä¸ä¸ªæ¥éª¤ï¼æä»¥ä¸æ¯ååæ§çï¼å¹¶åæ¶ä¼é ææ°æ®ä¸ä¸è´çé®é¢ã
主è¦å®ç°åçæ¯AtomicIntegerç±»æä¸ä¸ªunsafe屿§ï¼å¯ä»¥éè¿unsafeæ¥è°ç¨Unsafeç±»çä¸äºååæ§çæ¹æ³Unsafe.compareAndSwapIntæ¥å®ç°ååæ§çå åè¿ç®ã
å
¶æ¬¡æ¯ä½¿ç¨volatileæ¥ä¿®é¥°value屿§ï¼ä¿è¯ä¸ä¸ªå
åå¯è§æ§
```
//compareAndSwapIntæåä¸ªåæ°ï¼ç¬¬ä¸ä¸ªæ¯å¾
è¿ç®ç对象ï¼ç¬¬äºä¸ªæ¯å¯¹è±¡ä¸ç¨äºè¿ç®ç屿§çåç§»éï¼ç¬¬ä¸ä¸ªæ¯ææå¼ï¼ç¬¬åä¸ªæ¯æ´æ°çå¼ã
unsafe.compareAndSwapInt(this, valueOffset, expect, update)
```
```
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;//使ç¨volatioleæ¥ä¿è¯valueçå
åå¯è§æ§
}
```
å¨Unsafeç±»ä¸ï¼compareAndSwapIntågetAndAddIntçåºå«å¨äºï¼getAndAddIntä¼ä¸ç´éè¯ç´å°æåï¼compareAndSwapIntå¦ææ´æ°å¤±è´¥ï¼åªä¼è¿åfalse
```
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
```
### volatileå
³é®åæä»ä¹ç¨ï¼æä¹çè§£å¯è§æ§ï¼ä¸è¬ä»ä¹åºæ¯å»ç¨å¯è§æ§ï¼
å½çº¿ç¨è¿è¡ä¸ä¸ªvolatileåéçåæä½æ¶ï¼JITç¼è¯å¨çæçæ±ç¼æä»¤ä¼å¨åæä½çæä»¤åé¢å ä¸ä¸ä¸ªâlockâæä»¤ã
Java代ç å¦ä¸:
```java
instance = new Singleton(); // instanceæ¯volatileåé
è½¬åææ±ç¼ä»£ç ï¼å¦ä¸ã
0x01a3de1d: movb $0Ã0,0Ã1104800(%esi);0x01a3de24: lock addl $0Ã0,(%esp);
```
âlockâæä¸ä¸ªä½ç¨ï¼
1.å°å½åCPUç¼åè¡çæ°æ®ä¼ååå°ç³»ç»å
åã
2.è¿ä¸ªååå
åçæä½ä¼ä½¿å¾å
¶ä»CPUéç¼åäºè¯¥å
åå°åçæ°æ®æ æã
3.ç¡®ä¿æä»¤éæåºæ¶ï¼å
åå±éåçæä»¤ä¸ä¼æå°åé¢å»ï¼å
åå±éåçæä»¤ä¸ä¼æå°åé¢å»ã
å¯è§æ§å¯ä»¥ç解为ä¸ä¸ªçº¿ç¨çåæä½å¯ä»¥ç«å³è¢«å
¶ä»çº¿ç¨å¾ç¥ãä¸ºäºæé«CPUå¤çé度ï¼CPUä¸è¬ä¸ç´æ¥ä¸å
åè¿è¡éä¿¡ï¼èæ¯å°ç³»ç»å
åçæ°æ®è¯»å°å
é¨ç¼åï¼åè¿è¡æä½ï¼å¯¹äºæ®éçåéï¼ä¿®æ¹å®ä¸ç¥é使¶ä¼æ´æ°å°ç³»ç»å
åã使¯å¦ææ¯å¯¹volatile修饰çåéè¿è¡åæä½ï¼JVMå°±ä¼åå¤çå¨åé䏿¡Lockåç¼çæä»¤ï¼å°è¿ä¸ªåéæå¨çç¼åè¡çæ°æ®ç«å³ååå°ç³»ç»å
åã使¯å³ä¾¿ååå°ç³»ç»å
åï¼å
¶ä»CPUä¸çç¼åè¡æ°æ®è¿æ¯æ§çï¼ä¸ºäºä¿è¯æ°æ®ä¸è´æ§ï¼å
¶ä»CPUä¼å
æ¢å¨æ»çº¿ä¸ä¼ æçæ°æ®æ¥æ£æ¥èªå·±çç¼åè¡ç弿¯å¦è¿æï¼å½CPUåç°ç¼åè¡å¯¹åºçå
åå°å被修æ¹ï¼é£ä¹å°±ä¼å°å½åç¼åè¡è®¾ç½®ä¸ºæ æï¼ä¸æ¬¡å½CPU对è¿ä¸ªç¼åè¡ä¸ çæ°æ®è¿è¡ä¿®æ¹æ¶ï¼ä¼éæ°ä»ç³»ç»å
åä¸ææ°æ®è¯»å°å¤çå¨ç¼å éã
##### 使ç¨åºæ¯
##### 读åé
妿éè¦å®ç°ä¸ä¸ªè¯»åéï¼æ¯æ¬¡åªè½ä¸ä¸ªçº¿ç¨å»åæ°æ®ï¼ä½æ¯æå¤ä¸ªçº¿ç¨æ¥è¯»æ°æ®ï¼å°±synchronize忥鿥坹setæ¹æ³å éï¼getæ¹æ³ä¸å éï¼ ä½¿ç¨volatileæ¥ä¿®é¥°åéï¼ä¿è¯å
åå¯è§æ§ï¼ä¸ç¶å¤ä¸ªçº¿ç¨å¯è½ä¼å¨åéä¿®æ¹åè¿è¯»å°ä¸ä¸ªæ§å¼ã
##### ç¶æä½
ç¨äºåç¶æä½æ å¿ï¼å¦æå¤ä¸ªçº¿ç¨å»éè¦æ ¹æ®ä¸ä¸ªç¶æä½æ¥æ§è¡ä¸äºæä½ï¼ä½¿ç¨volatile修饰å¯ä»¥ä¿è¯å
åå¯è§æ§ã
ç¨äºå便¨¡å¼ç¨äºä¿è¯å
åå¯è§æ§ï¼ä»¥å鲿¢æä»¤éæåºã
### sychronizeçå®ç°åçæ¯æä¹æ ·çï¼
```java
public class SyncTest {
public void syncBlock(){
synchronized (this){
System.out.println("hello block");
}
}
public synchronized void syncMethod(){
System.out.println("hello method");
}
}
```
å½SyncTest.java被ç¼è¯æclassæä»¶çæ¶åï¼`synchronized`å
³é®åå`synchronized`æ¹æ³çåèç ç¥æä¸åï¼æä»¬å¯ä»¥ç¨`javap -v` å½ä»¤æ¥çclassæä»¶å¯¹åºçJVMåèç ä¿¡æ¯ï¼é¨åä¿¡æ¯å¦ä¸ï¼
```java
{
public void syncBlock();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: aload_0
1: dup
2: astore_1
3: monitorenter // monitorenteræä»¤è¿å
¥åæ¥å
4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #3 // String hello block
9: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: aload_1
13: monitorexit // monitorexitæä»¤éåºåæ¥å
14: goto 22
17: astore_2
18: aload_1
19: monitorexit // monitorexitæä»¤éåºåæ¥å
20: aload_2
21: athrow
22: return
Exception table:
from to target type
4 14 17 any
17 20 17 any
public synchronized void syncMethod();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED //æ·»å äºACC_SYNCHRONIZEDæ è®°
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #5 // String hello method
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
```
对äº`synchronized`å
³é®åèè¨ï¼`javac`å¨ç¼è¯æ¶ï¼ä¼çæå¯¹åºç`monitorenter`å`monitorexit`æä»¤åå«å¯¹åº`synchronized`忥åçè¿å
¥åéåºï¼æä¸¤ä¸ª`monitorexit`æä»¤çåå æ¯ä¸ºäºä¿è¯æå¼å¸¸çæ
åµä¸ä¹è½éæ¾éï¼æä»¥`javac`ä¸ºåæ¥ä»£ç åæ·»å äºä¸ä¸ªéå¼çtry-finallyï¼å¨finallyä¸ä¼è°ç¨`monitorexit`å½ä»¤éæ¾éã
è对äº`synchronized`æ¹æ³èè¨ï¼`javac`为å
¶çæäºä¸ä¸ª`ACC_SYNCHRONIZED`å
³é®åï¼å¨JVMè¿è¡æ¹æ³è°ç¨æ¶ï¼åç°è°ç¨çæ¹æ³è¢«`ACC_SYNCHRONIZED`修饰ï¼åä¼å
å°è¯è·å¾éã
#### é
è¿æ¯ç½ä¸çå°çä¸ä¸ªæµç¨å¾ï¼

å°±æ¯Java对象çå
åå¸å±å
¶å®ç±å¯¹è±¡å¤´+å®ä¾æ°æ®+对é½å¡«å
ä¸é¨åç»æï¼è对象头主è¦å
å«Mark Word+æå对象æå±çç±»çæéç»æãMark Word主è¦ç¨äºåå¨å¯¹è±¡èªèº«çè¿è¡æ¶æ°æ®ï¼åå¸ç ï¼GCå代年é¾ï¼éæ å¿çã
ä¸é¢å°±æ¯Mark Wordçæ°æ®æ å°è¡¨

##### ååé
æ ¹æ®ä¸é¢ç表æ¥çï¼Mark Wordåä¸ä½ä¸º101æ¶ï¼å é对象çç¶æä¸ºååéï¼ååéçæä¹å¨äºåä¸ä¸ªçº¿ç¨è®¿é®sychronize代ç åæ¶ä¸éè¦è¿è¡å éï¼è§£éæä½ï¼æ§è½å¼éæ´ä½ï¼HotSpot[1]çä½è
ç»è¿ç ç©¶åç°ï¼å¤§å¤æ°æ
åµä¸ï¼éä¸ä»
ä¸åå¨å¤çº¿ç¨ç«äºï¼è䏿»æ¯ç±åä¸çº¿ç¨å¤æ¬¡è·å¾ï¼ä¸ºäºè®©çº¿ç¨è·å¾éç代价æ´ä½èå¼å
¥äºååéãï¼
å 为æ£å¸¸æ
åµä¸ï¼å½ä¸ä¸ªçº¿ç¨è®¿é®åæ¥åå¹¶è·åè½»éçº§éæ¶ï¼éè¦è¿è¡CASæä½å°å¯¹è±¡å¤´çéè®°å½éæåå½å线ç¨çæ ä¸çéè®°å½ï¼æ§è¡å®æ¯åéè¦éæ¾è½»é级éã妿æ¯åä¸ä¸ªçº¿ç¨å¤æ¬¡è®¿é®sychronize代ç åï¼å¤æ¬¡è·ååéæ¾è½»é级ï¼å¼éä¼åå¤§ï¼æä»¥ä¼ä¸å¼å§å¤æå¯¹è±¡æ¯æ éç¶æï¼ä¼å°å¯¹è±¡å¤´è®¾ç½®ä¸ºååéï¼å¹¶ä¸è¿ä¸ªç线ç¨IDå°Mark Wordï¼åç»åä¸çº¿ç¨å¤æå éæ å¿æ¯ååéï¼å¹¶ä¸çº¿ç¨IDä¸è´å°±å¯ä»¥ç´æ¥æ§è¡ã

#### è½»é级é
JVMçå¼åè
åç°å¨å¾å¤æ
åµä¸ï¼å¨Javaç¨åºè¿è¡æ¶ï¼åæ¥åä¸ç代ç 齿¯ä¸åå¨ç«äºçï¼ä¸åç线ç¨äº¤æ¿çæ§è¡åæ¥åä¸ç代ç ãè¿ç§æ
åµä¸ï¼ç¨ééçº§éæ¯æ²¡å¿
è¦çãå æ¤JVMå¼å
¥äºè½»é级éçæ¦å¿µã
线ç¨å¨æ§è¡åæ¥åä¹åï¼JVMä¼å
å¨å½åç线ç¨çæ 帧ä¸å建ä¸ä¸ª`Lock Record`ï¼å
¶å
æ¬ä¸ä¸ªç¨äºåå¨å¯¹è±¡å¤´ä¸ç `mark word`ï¼å®æ¹ç§°ä¹ä¸º`Displaced Mark Word`ï¼ä»¥åä¸ä¸ªæå对象çæéãä¸å¾å³è¾¹çé¨åå°±æ¯ä¸ä¸ª`Lock Record`ã

(1)è½»é级éå é
线ç¨å¨æ§è¡åæ¥åä¹åï¼JVMä¼å
å¨å½å线ç¨çæ æ¡¢ä¸å建ç¨äºåå¨éè®°å½ç空é´ï¼å¹¶ å°å¯¹è±¡å¤´ä¸çMark Wordå¤å¶å°éè®°å½ä¸ï¼å®æ¹ç§°ä¸ºDisplaced Mark Wordãç¶å线ç¨å°è¯ä½¿ç¨ CASå°å¯¹è±¡å¤´ä¸çMark Wordæ¿æ¢ä¸ºæåéè®°å½çæéã妿æåï¼å½å线ç¨è·å¾éï¼å¦æå¤±è´¥ï¼è¡¨ç¤ºå
¶ä»çº¿ç¨ç«äºéï¼å½å线ç¨ä¾¿å°è¯ä½¿ç¨èªææ¥è·åéï¼èªæè·åéå¤±è´¥çæ¬¡æ°è¾¾å°ä¸å®æ¬¡æ°åå°±ä¼è¿è¡éå级ï¼å°éå级为éé级éï¼å½å线ç¨å°±ä¼è¢«é»å¡ï¼ç´å°è·å¾è½»é级éççº¿ç¨æ§è¡å®æ¯ï¼éæ¾éï¼å¤éé»å¡ç线ç¨ã
(2)è½»é级éè§£é
è½»éçº§è§£éæ¶ï¼ä¼ä½¿ç¨ååçCASæä½å°Displaced Mark Wordæ¿æ¢åå°å¯¹è±¡å¤´ï¼å¦ææ åï¼å表示没æç«äºåçãå¦æå¤±è´¥ï¼è¡¨ç¤ºå½åéåå¨ç«äºï¼éå°±ä¼è¨èæéé级éãå¾2-2æ¯ ä¸¤ä¸ªçº¿ç¨åæ¶äºå¤ºéï¼å¯¼è´éè¨èçæµç¨å¾ã

### éé级é
ééçº§éæ¯æä»¬å¸¸è¯´çä¼ ç»æä¹ä¸çéï¼å
¶å©ç¨æä½ç³»ç»åºå±ç忥æºå¶å»å®ç°Javaä¸ç线ç¨åæ¥ã
éé级éçç¶æä¸ï¼å¯¹è±¡ç`mark word`为æåä¸ä¸ªå ä¸monitor对象çæéã
ä¸ä¸ªmonitor对象å
æ¬è¿ä¹å 个å
³é®å段ï¼cxqï¼ä¸å¾ä¸çContentionListï¼ï¼EntryList ï¼WaitSetï¼ownerã
å
¶ä¸cxq ï¼EntryList ï¼WaitSet齿¯ç±ObjectWaiterçé¾è¡¨ç»æï¼owneræåææéç线ç¨ã

å½ä¸ä¸ªçº¿ç¨å°è¯è·å¾éæ¶ï¼å¦æè¯¥éå·²ç»è¢«å ç¨ï¼åä¼å°è¯¥çº¿ç¨å°è£
æä¸ä¸ªObjectWaiter对象æå
¥å°cxqçéåå°¾é¨ï¼ç¶åæåå½å线ç¨ã彿æéç线ç¨éæ¾éåï¼ä¼å°cxqä¸çææå
ç´ ç§»å¨å°EntryListä¸å»ï¼å¹¶å¤éEntryListçéé¦çº¿ç¨ã
妿ä¸ä¸ªçº¿ç¨å¨åæ¥åä¸è°ç¨äº`Object#wait`æ¹æ³ï¼ä¼å°è¯¥çº¿ç¨å¯¹åºçObjectWaiterä»EntryListç§»é¤å¹¶å å
¥å°WaitSetä¸ï¼ç¶åéæ¾éãå½waitç线ç¨è¢«notifyä¹åï¼ä¼å°å¯¹åºçObjectWaiterä»WaitSetç§»å¨å°EntryListä¸ã
#### ä¸ç§éçä¼ç¼ºç¹å¯¹æ¯

åèæç« ï¼
[æ»ç£Synchronizedåºå±å®ç°--æ¦è®º](https://github.com/farmerjohngit/myblog/issues/12)
[æµ
è°ååéãè½»é级éãéé级é](https://www.jianshu.com/p/36eedeb3f912)
### è¿ç¨å线ç¨çåºå«ï¼å¹¶è¡åå¹¶åçåºå«ï¼äºè§£åç¨ä¹ï¼
#### æ¹å¤çæä½ç³»ç»
**æ¹å¤çæä½ç³»ç»**å°±æ¯æä¸ç³»åéè¦æä½çæä»¤å䏿¥ï¼å½¢æä¸ä¸ªæ¸
åï¼ä¸æ¬¡æ§äº¤ç»è®¡ç®æºãç¨æ·å°å¤ä¸ªéè¦æ§è¡çç¨åºåå¨ç£å¸¦ä¸ï¼ç¶å交ç±è®¡ç®æºå»è¯»åå¹¶é个æ§è¡è¿äºç¨åºï¼å¹¶å°è¾åºç»æåå¨å¦ä¸ä¸ªç£å¸¦ä¸ã
æ¹å¤çæä½ç³»ç»å¨ä¸å®ç¨åº¦ä¸æé«äºè®¡ç®æºçæçï¼ä½æ¯ç±äº**æ¹å¤çæä½ç³»ç»çæä»¤è¿è¡æ¹å¼ä»ç¶æ¯ä¸²è¡çï¼å
åä¸å§ç»åªæä¸ä¸ªç¨åºå¨è¿è¡**ï¼åé¢çç¨åºéè¦çå¾
åé¢çç¨åºæ§è¡å®æåæè½å¼å§æ§è¡ï¼èåé¢çç¨åºææ¶ä¼ç±äºI/Oæä½ãç½ç»çåå é»å¡ï¼å¯¼è´CPUé²ç½®æä»¥**æ¹å¤çæä½æçä¹ä¸é«**ã
#### è¿ç¨çæåº
æ¹å¤çæä½ç³»ç»çç¶é¢å¨äºå
åä¸åªåå¨ä¸ä¸ªç¨åºï¼è¿ç¨çæåºï¼å¯ä»¥è®©å
åä¸åå¨å¤ä¸ªç¨åºï¼æ¯ä¸ªç¨åºå¯¹åºä¸ä¸ªè¿ç¨ï¼è¿ç¨æ¯æä½ç³»ç»èµæºåé
çæå°åä½ãCPUéç¨æ¶é´çè½®è½¬çæ¹å¼è¿è¡è¿ç¨ï¼CPU为æ¯ä¸ªè¿ç¨åé
ä¸ä¸ªæ¶é´æ®µï¼ç§°ä½å®çæ¶é´çã妿卿¶é´çç»ææ¶è¿ç¨è¿å¨è¿è¡ï¼åæåè¿ä¸ªè¿ç¨çè¿è¡ï¼å¹¶ä¸CPUåé
ç»å¦ä¸ä¸ªè¿ç¨ï¼è¿ä¸ªè¿ç¨å«åä¸ä¸æåæ¢ï¼ã妿è¿ç¨å¨æ¶é´çç»æåé»å¡æç»æï¼åCPUç«å³è¿è¡åæ¢ï¼ä¸ç¨çå¾
æ¶é´çç¨å®ãå¤è¿ç¨ç好å¤å¨äºä¸ä¸ªå¨è¿è¡IOæä½æ¶å¯ä»¥è®©åºCPUæ¶é´çï¼è®©CPUæ§è¡å
¶ä»è¿ç¨çä»»å¡ã
#### 线ç¨çæåº
éçè®¡ç®æºçåå±ï¼å¯¹CPUçè¦æ±è¶æ¥è¶é«ï¼è¿ç¨ä¹é´ç忢å¼éè¾å¤§ï¼å·²ç»æ æ³æ»¡è¶³è¶æ¥è¶å¤æçç¨åºçè¦æ±äºãäºæ¯å°±åæäºçº¿ç¨ï¼çº¿ç¨æ¯ç¨åºæ§è¡ä¸ä¸ä¸ªåä¸çé¡ºåºæ§å¶æµç¨ï¼æ¯ç¨åºæ§è¡æµçæå°åå
ï¼æ¯å¤çå¨è°åº¦ååæ´¾çåºæ¬åä½ãä¸ä¸ªè¿ç¨å¯ä»¥æä¸ä¸ªæå¤ä¸ªçº¿ç¨ï¼å个线ç¨ä¹é´å
±äº«ç¨åºçå
å空é´(ä¹å°±æ¯æå¨è¿ç¨çå
å空é´)ã
#### è¿ç¨å线ç¨çåºå«
è¿ç¨æ¯ä¸ä¸ªç¬ç«çè¿è¡ç¯å¢ï¼èçº¿ç¨æ¯å¨è¿ç¨ä¸æ§è¡çä¸ä¸ªä»»å¡ãä»ä»¬ä¸¤ä¸ªæ¬è´¨çåºå«æ¯æ¯å¦**åç¬å æå
åå°å空é´åå
¶å®ç³»ç»èµæºï¼æ¯å¦I/Oï¼**ï¼
* è¿ç¨åç¬å æä¸å®çå
åå°å空é´ï¼æä»¥è¿ç¨é´åå¨å
åéç¦»ï¼æ°æ®æ¯åå¼çï¼æ°æ®å
±äº«å¤æä½æ¯åæ¥ç®åï¼å个è¿ç¨ä¹é´äºä¸å¹²æ°ï¼è线ç¨å
±äº«æå±è¿ç¨å æçå
åå°å空é´åèµæºï¼æ°æ®å
±äº«ç®åï¼ä½æ¯åæ¥å¤æã
* è¿ç¨åç¬å æä¸å®çå
åå°å空é´ï¼ä¸ä¸ªè¿ç¨åºç°é®é¢ä¸ä¼å½±åå
¶ä»è¿ç¨ï¼ä¸å½±å主ç¨åºçç¨³å®æ§ï¼å¯é æ§é«ï¼ä¸ä¸ªçº¿ç¨å´©æºå¯è½å½±åæ´ä¸ªç¨åºçç¨³å®æ§ï¼å¯é æ§è¾ä½ã
* è¿ç¨åç¬å æä¸å®çå
åå°å空é´ï¼è¿ç¨çå建å鿝ä¸ä»
éè¦ä¿åå¯åå¨åæ ä¿¡æ¯ï¼è¿éè¦èµæºçåé
忶以å页è°åº¦ï¼å¼éè¾å¤§ï¼çº¿ç¨åªéè¦ä¿åå¯åå¨åæ ä¿¡æ¯ï¼å¼éè¾å°ã
å¦å¤ä¸ä¸ªéè¦åºå«æ¯ï¼è¿ç¨æ¯æä½ç³»ç»è¿è¡èµæºåé
çåºæ¬åä½ï¼èçº¿ç¨æ¯æä½ç³»ç»è¿è¡è°åº¦çåºæ¬åä½ï¼å³CPUåé
æ¶é´çåä½ ã
#### Javaä¸çº¿ç¨çç¶ææ¯æä¹æ ·çï¼
卿ä½ç³»ç»ä¸ï¼çº¿ç¨çåäºè½»é级çè¿ç¨ã

æä»¥ä¼ ç»çæä½ç³»ç»çº¿ç¨ä¸è¬æä»¥ä¸ç¶æ
1. æ°å»ºç¶æ:
ä½¿ç¨ new å
³é®åå Thread ç±»æå
¶å类建ç«ä¸ä¸ªçº¿ç¨å¯¹è±¡åï¼è¯¥çº¿ç¨å¯¹è±¡å°±å¤äºæ°å»ºç¶æãå®ä¿æè¿ä¸ªç¶æç´å°ç¨åº start() è¿ä¸ªçº¿ç¨ã
2. å°±ç»ªç¶æ:
å½çº¿ç¨å¯¹è±¡è°ç¨äºstart()æ¹æ³ä¹åï¼è¯¥çº¿ç¨å°±è¿å
¥å°±ç»ªç¶æãå°±ç»ªç¶æç线ç¨å¤äºå°±ç»ªéåä¸ï¼è¦çå¾
JVMé线ç¨è°åº¦å¨çè°åº¦ã
3. è¿è¡ç¶æ:
å¦æå°±ç»ªç¶æç线ç¨è·å CPU èµæºï¼å°±å¯ä»¥æ§è¡ run()ï¼æ¤æ¶çº¿ç¨ä¾¿å¤äºè¿è¡ç¶æãå¤äºè¿è¡ç¶æççº¿ç¨æä¸ºå¤æï¼å®å¯ä»¥å为é»å¡ç¶æãå°±ç»ªç¶æåæ»äº¡ç¶æã
4. é»å¡ç¶æ:
妿ä¸ä¸ªçº¿ç¨æ§è¡äºsleepï¼ç¡ç ï¼ãsuspendï¼æèµ·ï¼çæ¹æ³ï¼å¤±å»æå ç¨èµæºä¹åï¼è¯¥çº¿ç¨å°±ä»è¿è¡ç¶æè¿å
¥é»å¡ç¶æãå¨ç¡ç æ¶é´å·²å°æè·å¾è®¾å¤èµæºåå¯ä»¥éæ°è¿å
¥å°±ç»ªç¶æãå¯ä»¥å为ä¸ç§ï¼
- çå¾
é»å¡ï¼è¿è¡ç¶æä¸ççº¿ç¨æ§è¡ wait() æ¹æ³ï¼ä½¿çº¿ç¨è¿å
¥å°çå¾
é»å¡ç¶æã
- 忥é»å¡ï¼çº¿ç¨å¨è·å synchronized忥é失败(å ä¸ºåæ¥é被å
¶ä»çº¿ç¨å ç¨)ã
- å
¶ä»é»å¡ï¼éè¿è°ç¨çº¿ç¨ç sleep() æ join() ååºäº I/Oè¯·æ±æ¶ï¼çº¿ç¨å°±ä¼è¿å
¥å°é»å¡ç¶æãå½sleep() ç¶æè¶
æ¶ï¼join() çå¾
线ç¨ç»æ¢æè¶
æ¶ï¼æè
I/O å¤ç宿¯ï¼çº¿ç¨éæ°è½¬å
¥å°±ç»ªç¶æã
5. æ»äº¡ç¶æ:
ä¸ä¸ªè¿è¡ç¶æç线ç¨å®æä»»å¡æè
å
¶ä»ç»æ¢æ¡ä»¶åçæ¶ï¼è¯¥çº¿ç¨å°±åæ¢å°ç»æ¢ç¶æã
使¯Javaä¸Thread对象çç¶æååè·ä¼ ç»çæä½ç³»ç»çº¿ç¨ç¶ææä¸äºåºå«ã
```java
public enum State {
NEW,//æ°å»ºæ
RUNNABLE,//è¿è¡æ
BLOCKED,//é»å¡æ
WAITING,//çå¾
æ
TIMED_WAITING,//ææ¶é´éå¶ççå¾
æ
TERMINATED;//æ»äº¡æ
}
```

#### NEW æ°å»ºæ
å¤äºNEWç¶æççº¿ç¨æ¤æ¶å°æªå¯å¨ï¼è¿æ²¡è°ç¨Threadå®ä¾çstart()æ¹æ³ã
#### RUNNABLE è¿è¡æ
表示å½åçº¿ç¨æ£å¨è¿è¡ä¸ãå¤äºRUNNABLEç¶æç线ç¨å¯è½å¨Javaèææºä¸è¿è¡ï¼ä¹æå¯è½å¨çå¾
å
¶ä»ç³»ç»èµæºï¼æ¯å¦I/Oï¼ã
> Java线ç¨ç**RUNNABLE**ç¶æå
¶å®æ¯å
æ¬äºä¼ ç»æä½ç³»ç»çº¿ç¨ç**ready**å**running**ä¸¤ä¸ªç¶æçã
#### BLOCKED é»å¡æ
é»å¡ç¶æãå¤äºBLOCKEDç¶æççº¿ç¨æ£çå¾
éç鿾以è¿å
¥åæ¥åºã
#### WAITING çå¾
æ
çå¾
ç¶æãå¤äºçå¾
ç¶æç线ç¨åæRUNNABLEç¶æéè¦å
¶ä»çº¿ç¨å¤éã
è°ç¨å¦ä¸3ä¸ªæ¹æ³ä¼ä½¿çº¿ç¨è¿å
¥çå¾
ç¶æï¼
- Object.wait()ï¼ä½¿å½å线ç¨å¤äºçå¾
ç¶æç´å°å¦ä¸ä¸ªçº¿ç¨è°ç¨notifyå¤éå®ï¼
- Thread.join()ï¼çå¾
çº¿ç¨æ§è¡å®æ¯ï¼åºå±è°ç¨çæ¯Objectå®ä¾çwait()æ¹æ³ï¼
- LockSupport.park()ï¼é¤éè·å¾è°ç¨è®¸å¯ï¼å¦åç¦ç¨å½å线ç¨è¿è¡çº¿ç¨è°åº¦ã
#### TIMED_WAITING è¶
æ¶çå¾
ç¶æ
è¶
æ¶çå¾
ç¶æã线ç¨çå¾
ä¸ä¸ªå
·ä½çæ¶é´ï¼æ¶é´å°åä¼è¢«èªå¨å¤éã
è°ç¨å¦ä¸æ¹æ³ä¼ä½¿çº¿ç¨è¿å
¥è¶
æ¶çå¾
ç¶æï¼
- Thread.sleep(long millis)ï¼ä½¿å½å线ç¨ç¡ç æå®æ¶é´ï¼
- Object.wait(long timeout)ï¼çº¿ç¨ä¼ç æå®æ¶é´ï¼çå¾
æé´å¯ä»¥éè¿notify()/notifyAll()å¤éï¼
- Thread.join(long millis)ï¼çå¾
å½åçº¿ç¨æå¤æ§è¡millis毫ç§ï¼å¦æmillis为0ï¼åä¼ä¸ç´æ§è¡ï¼
- LockSupport.parkNanos(long nanos)ï¼ é¤éè·å¾è°ç¨è®¸å¯ï¼å¦åç¦ç¨å½å线ç¨è¿è¡çº¿ç¨è°åº¦æå®æ¶é´ï¼
- LockSupport.parkUntil(long deadline)ï¼åä¸ï¼ä¹æ¯ç¦æ¢çº¿ç¨è¿è¡è°åº¦æå®æ¶é´ï¼
#### TERMINATED ç»æ¢æ
ç»æ¢ç¶æãæ¤æ¶çº¿ç¨å·²æ§è¡å®æ¯ã
#### ç¶æè½¬æ¢
1.BLOCKEDä¸RUNNABLEç¶æç转æ¢
å¤äºBLOCKEDç¶æççº¿ç¨æ¯å 为å¨çå¾
éçéæ¾ï¼å½è·å¾éä¹å就转æ¢ä¸ºRUNNABLEç¶æã
2.WAITINGç¶æä¸RUNNABLEç¶æç转æ¢
**Object.wait()**ï¼**Thread.join()**å**LockSupport.park()**è¿3ä¸ªæ¹æ³å¯ä»¥ä½¿çº¿ç¨ä»RUNNABLEç¶æè½¬ä¸ºWAITINGç¶æã
3.TIMED_WAITINGä¸RUNNABLEç¶æè½¬æ¢
TIMED_WAITINGä¸WAITINGç¶æç±»ä¼¼ï¼åªæ¯TIMED_WAITINGç¶æçå¾
çæ¶é´æ¯æå®çã
è°ç¨**Thread.sleep(long)**ï¼**Object.wait(long)**ï¼**Thread.join(long)**ä¼ä½¿å¾RUNNABLEç¶æè½¬æ¢ä¸ºTIMED_WAITINGç¶æ
### Java线ç¨é´çéä¿¡
é¦å
éè¦å¯¹wait()ï¼join()ï¼sleep()æ¹æ³è¿è¡ä»ç»ã
#### Object.wait()æ¹æ³æ¯ä»ä¹ï¼
è°ç¨wait()æ¹æ³å线ç¨å¿
é¡»ææå¯¹è±¡Objectçéã线ç¨è°ç¨wait()æ¹æ³åï¼ä¼éæ¾å½åçObjectéï¼è¿å
¥éçmonitor对象ççå¾
éåï¼ç´å°æå
¶ä»çº¿ç¨è°ç¨notify()/notifyAll()æ¹æ³å¤éçå¾
éç线ç¨ã
éè¦æ³¨æçæ¯ï¼å
¶ä»çº¿ç¨è°ç¨notify()æ¹æ³åªä¼å¤éå个çå¾
éç线ç¨ï¼å¦ææå¤ä¸ªçº¿ç¨é½å¨çå¾
è¿ä¸ªéçè¯ï¼ä¸ä¸å®ä¼å¤éå°ä¹åè°ç¨wait()æ¹æ³ç线ç¨ã
åæ ·ï¼è°ç¨notifyAll()æ¹æ³å¤éææçå¾
éç线ç¨ä¹åï¼ä¹ä¸ä¸å®ä¼é©¬ä¸ææ¶é´çåç»åææ¾å¼éçé£ä¸ªçº¿ç¨ï¼å
·ä½è¦çç³»ç»çè°åº¦ã
#### Thread.join()æ¹æ³æ¯ä»ä¹ï¼
join()æ¹æ³æ¯Threadç±»çä¸ä¸ªå®ä¾æ¹æ³ãå®çä½ç¨æ¯è®©å½å线ç¨é·å
¥âçå¾
âç¶æï¼çjoinçè¿ä¸ªçº¿ç¨threadAæ§è¡å®æåï¼åç»§ç»æ§è¡å½å线ç¨ã
å®ç°åçæ¯join()æ¹æ³æ¬èº«æ¯ä¸ä¸ªsychronizedä¿®é¥°çæ¹æ³ï¼ä¹å°±æ¯è°ç¨join()è¿ä¸ªæ¹æ³éè¦å
è·åthreadAçéï¼è·å¾éä¹ååè°ç¨wait()æ¹æ³æ¥è¿è¡çå¾
ï¼ä¸ç´å°threadAæ§è¡å®æåï¼threadAä¼è°ç¨notify_all()æ¹æ³,å¤éææçå¾
ç线ç¨ï¼å½åçº¿ç¨æä¼ç»æçå¾
ã
```
Thread threadA = new Thread();
threadA.join();
```
join()æ¹æ³çæºç ï¼
```java
public final void join() throws InterruptedException {
join(0);//0çè¯ä»£è¡¨æ²¡æè¶
æ¶æ¶é´ä¸ç´çä¸å»
}
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
```
è¿æ¯jvmä¸Theadçæºç ï¼å¨çº¿ç¨æ§è¡ç»æåä¼è°ç¨notify_allæ¥å¤éçå¾
ç线ç¨ã
```java
//ä¸ä¸ªc++彿°ï¼
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ï¼
//é颿ä¸ä¸ªè´¼ä¸èµ·ç¼çä¸è¡ä»£ç
ensure_join(this);
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
ObjectLocker lock(threadObj, thread);
thread->clear_pending_exception();
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
java_lang_Thread::set_thread(threadObj(), NULL);
//åå¿ä»¬çå°äºæ²¡ï¼å«çä¸ç¨çï¼å°±çè¿ä¸å¥
//threadå°±æ¯å½å线ç¨ï¼æ¯å¥ï¼å°±æ¯åæä¾åä¸è¯´çthreadA线ç¨
lock.notify_all(thread);
thread->clear_pending_exception();
}
```
#### sleep()æ¹æ³æ¯ä»ä¹ï¼
sleepæ¹æ³æ¯Threadç±»çä¸ä¸ªéææ¹æ³ãå®çä½ç¨æ¯è®©å½å线ç¨ç¡ç 䏿®µæ¶é´ãï¼**sleepæ¹æ³æ¯ä¸ä¼éæ¾å½åçéçï¼èwaitæ¹æ³ä¼ã**
sleepä¸waitæ¹æ³çåºå«ï¼
- waitå¯ä»¥æå®æ¶é´ï¼ä¹å¯ä»¥ä¸æå®ï¼èsleepå¿
é¡»æå®æ¶é´ã
- waitéæ¾cpuèµæºï¼åæ¶éæ¾éï¼sleepéæ¾cpuèµæºï¼ä½æ¯ä¸éæ¾éï¼æä»¥ææ»éãï¼è°ç¨join()æ¹æ³ä¹ä¸ä¼éæ¾éï¼
- waitå¿
é¡»æ¾å¨åæ¥åæåæ¥æ¹æ³ä¸ï¼èsleepå¯ä»¥åä»»æä½ç½®ã
åèæç« ï¼
http://redspider.group:4000/article/01/4.html
https://www.jianshu.com/p/5d88b122a050
### 线ç¨é´æä¹éä¿¡ï¼
1.éè¿sychronized鿥è¿è¡åæ¥ï¼è®©ä¸æ¬¡åªè½ä¸ä¸ªçº¿ç¨æ¥æ§è¡ã
#### 2.çå¾
/éç¥æºå¶
```java
//å设æä»¬çéæ±æ¯Bæ§è¡ç»æåAæè½æ§è¡
//线ç¨Aç代ç
synchronized(对象) { while(æ¡ä»¶ä¸æ»¡è¶³) {
while(æ¡ä»¶ä¸æ»¡è¶³) {
对象.wait(); //线ç¨Aè¿è¡çå¾
}
//线ç¨Aæ§è¡ç¸å
³ççé»è¾
}
//线ç¨Bç代ç
synchronized(对象) {
//线ç¨Bæ§è¡ç¸å
³ççé»è¾
//线ç¨Bå¤é线ç¨A
对象.notifyAll();
}
```
çå¾
/éç¥æºå¶ï¼æ¯æä¸ä¸ªçº¿ç¨Aè°ç¨äºå¯¹è±¡objectAçwait()æ¹æ³è¿å
¥çå¾
ç¶æï¼èå¦ä¸ä¸ªçº¿ç¨Bè°ç¨äºå¯¹è±¡objectAçnotify()æè
notifyAll()æ¹æ³ï¼çº¿ç¨Aæ¶å°éç¥åä»å¯¹è±¡objectAçwait()æ¹æ³è¿åï¼è¿èæ§è¡åç»æä½ãä¸è¿°ä¸¤ä¸ªçº¿ç¨éè¿å¯¹è±¡objectAæ¥å®æäº¤äºï¼è对象ä¸çwait()ånotify/notifyAll()çå
³ç³»å°±å¦åå¼å
³ä¿¡å·ä¸æ ·ï¼ç¨æ¥å®æçå¾
æ¹åéç¥æ¹ä¹é´ç交äºå·¥ä½ã

1)使ç¨wait()ãnotify()ånotifyAll()æ¶éè¦å
对è°ç¨å¯¹è±¡å éã
2)è°ç¨wait()æ¹æ³åï¼çº¿ç¨ç¶æç±RUNNINGå为WAITINGï¼å¹¶å°å½åçº¿ç¨æ¾ç½®å°å¯¹è±¡ç
çå¾
éåã
3)notify()ænotifyAll()æ¹æ³è°ç¨åï¼çå¾
线ç¨ä¾æ§ä¸ä¼ä»wait()è¿åï¼å 为çå¾
线ç¨åªæ¯ä»çå¾
éåå°äºåæ¥éåï¼éè¦è°ç¨notify()æ notifAll()ç线ç¨éæ¾éä¹åï¼çå¾
线ç¨è·å¾éï¼æè½ä»åæ¥éåä¸ç§»é¤ï¼æææºä¼ä»wait()è¿åï¼æè½ç»§ç»å¾ä¸æ§è¡ã
4)notify()æ¹æ³å°çå¾
éåä¸çä¸ä¸ªçå¾
线ç¨ä»çå¾
éåä¸ç§»å°åæ¥éåä¸ï¼ènotifyAll() æ¹æ³åæ¯å°çå¾
éå䏿æç线ç¨å
¨é¨ç§»å°åæ¥éåï¼è¢«ç§»å¨ç线ç¨ç¶æç±WAITINGå为 BLOCKEDã
5)ä»wait()æ¹æ³è¿åçåææ¯è·å¾äºè°ç¨å¯¹è±¡çéã

##### 3.管é
管éè¾å
¥/è¾åºæµ 管éè¾å
¥/è¾åºæµåæ®éçæä»¶è¾å
¥/è¾åºæµæè
ç½ç»è¾å
¥/è¾åºæµä¸åä¹å¤å¨äºï¼å®ä¸»è¦ ç¨äºçº¿ç¨ä¹é´çæ°æ®ä¼ è¾ï¼èä¼ è¾çåªä»ä¸ºå
åã 管éè¾å
¥/è¾åºæµä¸»è¦å
æ¬äºå¦ä¸4ç§å
·ä½å®ç°:PipedOutputStreamãPipedInputStreamã PipedReaderåPipedWriterï¼å两ç§é¢ååèï¼èå两ç§é¢åå符ã
PipedReaderåPipedWriterå¯ä»¥ä¸ä¸ªçº¿ç¨Aè°ç¨PipedWriterå®ä¾çwrite()æ¹æ³ï¼å¾éé¢åæ°æ®ï¼ç¶åä¸PipedWriterå®ä¾å»ºç«è¿æ¥çPipedReaderå®ä¾å¯ä»¥è¯»å°æ°æ®ï¼çº¿ç¨Bå¯ä»¥éè¿PipedReaderå®ä¾è¯»å°æ°æ®ã
å¨ä»£ç æ¸
å4-12æç¤ºçä¾åä¸ï¼å建äºprintThreadï¼å®ç¨æ¥æ¥åmain线ç¨çè¾å
¥ï¼ä»»ä½ main线ç¨çè¾å
¥åéè¿PipedWriteråå
¥ï¼èprintThreadå¨å¦ä¸ç«¯éè¿PipedReaderå°å
容读åºå¹¶æå°ã
ä»£ç æ¸
å4-12 Piped.java
```
public class Piped {
public static void main(String[] args) throws Exception {
PipedWriter out = new PipedWriter();
PipedReader in = new PipedReader();
// å°è¾åºæµåè¾å
¥æµè¿è¡è¿æ¥ï¼å¦åå¨ä½¿ç¨æ¶ä¼æåºIOException out.connect(in);
Thread printThread = new Thread(new Print(in), "PrintThread"); printThread.start();
int receive = 0;
try {
while ((receive = System.in.read()) != -1) { out.write(receive);
}
} finally { out.close(); }
}
static class Print implements Runnable {
private PipedReader in;
public Print(PipedReader in) {
this.in = in;
}
public void run() {
int receive = 0;
try {
while ((receive = in.read()) != -1) { System.out.print((char) receive);
}
} catch (IOException ex) {
}
}
}
}
```
è¿è¡è¯¥ç¤ºä¾ï¼è¾å
¥ä¸ç»å符串ï¼å¯ä»¥çå°è¢«printThreadè¿è¡äºåæ ·è¾åºã
Repeat my words.
Repeat my words.
#### 4.Thread.join
Thread.join()ç使ç¨å¦æä¸ä¸ªçº¿ç¨Aæ§è¡äºthread.join()è¯å¥ï¼å½å线ç¨Aä¼ä¸ç´çå¾
thread线ç¨ç»æ¢ä¹åæä»thread.join()è¿åï¼å䏿§è¡ã线ç¨Threadé¤äºæä¾join()æ¹æ³ä¹å¤ï¼è¿æä¾äºjoin(long millis)åjoin(long millis,int nanos)两个å
·å¤è¶
æ¶åæ°çæ¹æ³ã
#### 5.ThreadLocalç使ç¨
ThreadLocalï¼å³çº¿ç¨åéï¼æ¯ä¸ä¸ªä»¥ThreadLocal对象为é®ãä»»æå¯¹è±¡ä¸ºå¼çåå¨ç»æãè¿ ä¸ªç»æè¢«é带å¨çº¿ç¨ä¸ï¼ä¹å°±æ¯è¯´ä¸ä¸ªçº¿ç¨å¯ä»¥æ ¹æ®ä¸ä¸ªThreadLocal对象æ¥è¯¢å°ç»å®å¨è¿ä¸ª 线ç¨ä¸çä¸ä¸ªå¼ã
```
public class Profiler {
// ç¬¬ä¸æ¬¡get()æ¹æ³è°ç¨æ¶ä¼è¿è¡åå§å(妿setæ¹æ³æ²¡æè°ç¨)ï¼æ¯ä¸ªçº¿ç¨ä¼è°ç¨ä¸æ¬¡
private static final ThreadLocal TIME_THREADLOCAL = new ThreadLocal() {
protected Long initialValue() { return System.currentTimeMillis();}
};
public static final void begin() {
TIME_THREADLOCAL.set(System.currentTimeMillis());
}
public static final long end() {
return System.currentTimeMillis() - TIME_THREADLOCAL.get();
}
public static void main(String[] args) throws Exception {
Profiler.begin();
TimeUnit.SECONDS.sleep(1);
System.out.println("Cost: " + Profiler.end() + " mills");
}
}
```
Profilerå¯ä»¥è¢«å¤ç¨å¨æ¹æ³è°ç¨èæ¶ç»è®¡çåè½ä¸ï¼å¨æ¹æ³çå
¥å£åæ§è¡begin()æ¹æ³ï¼å¨
æ¹æ³è°ç¨åæ§è¡end()æ¹æ³ï¼å¥½å¤æ¯ä¸¤ä¸ªæ¹æ³çè°ç¨ä¸ç¨å¨ä¸ä¸ªæ¹æ³æè
ç±»ä¸ï¼æ¯å¦å¨AOP(é¢ åæ¹é¢ç¼ç¨)ä¸ï¼å¯ä»¥å¨æ¹æ³è°ç¨åçåå
¥ç¹æ§è¡begin()æ¹æ³ï¼è卿¹æ³è°ç¨åçåå
¥ç¹æ§è¡ end()æ¹æ³ï¼è¿æ ·ä¾æ§å¯ä»¥è·å¾æ¹æ³çæ§è¡èæ¶ã