Javaå¹¶å常è§é¢è¯é¢æ»ç»
è¿æ¯ä¸åæè®¸å¯¹ä½ æå¸®å©çä¿¡æ¯
- é¢è¯æåï¼è¿æ¯ä¸ä»½å¤§å½¬ç²¾å¿æ´çç大åé¢è¯æåææ°çï¼ç®åå·²ç»æ´æ°è¿ä»£äº19ä¸ªçæ¬ï¼è´¨éå¾é«ï¼ä¸ä¸ºé¢è¯æé ï¼
- ç¥è¯æçï¼ä¸å±é¢è¯æå/ä¸å¯¹ä¸äº¤æµ/ç®åä¿®æ¹/è¶ æ£çå¦ä¹ æ°å´/å¦ä¹ 路线è§åï¼æ¬¢è¿å å ¥å¤§å½¬çç¥è¯æçï¼ç¹å»é¾æ¥æ¥çæçç详ç»ä»ç»ï¼
çº¿ç¨æ±
ä»ä¹æ¯çº¿ç¨æ± ï¼å¦ä½ä½¿ç¨ï¼ä¸ºä»ä¹è¦ä½¿ç¨çº¿ç¨æ± ï¼
çº¿ç¨æ± å°±æ¯äºå å°å¤ä¸ªçº¿ç¨å¯¹è±¡æ¾å°ä¸ä¸ªå®¹å¨ä¸ï¼ä½¿ç¨çæ¶åå°±ä¸ç¨new线ç¨èæ¯ç´æ¥å»æ± 䏿¿çº¿ç¨å³å¯ï¼èçäºå¼è¾å线ç¨çæ¶é´ï¼æé«äºä»£ç æ§è¡æçã
为ä»ä¹å¹³æ¶é½æ¯ä½¿ç¨çº¿ç¨æ± å建线ç¨ï¼ç´æ¥newä¸ä¸ªçº¿ç¨ä¸å¥½åï¼
å¯ï¼æå¨åå»ºçº¿ç¨æä¸¤ä¸ªç¼ºç¹
- ä¸åæ§é£é©
- é¢ç¹å建å¼é大
为ä»ä¹ä¸åæ§ï¼
ç³»ç»èµæºæéï¼æ¯ä¸ªäººé对ä¸åä¸å¡é½å¯ä»¥æå¨å建线ç¨ï¼å¹¶ä¸åå»ºçº¿ç¨æ²¡æç»ä¸æ åï¼æ¯å¦å建ççº¿ç¨ææ²¡æååçãå½ç³»ç»è¿è¡èµ·æ¥ï¼ææçº¿ç¨é½å¨æ¢å èµæºï¼æ¯«æ è§åï¼æ··ä¹±åºé¢å¯æ³èç¥ï¼ä¸å¥½ç®¡æ§ã
é¢ç¹æå¨å建线ç¨ä¸ºä»ä¹å¼éä¼å¤§ï¼è·new Object() æä»ä¹å·®å«ï¼
è½ç¶Javaä¸ä¸ç©ç对象ï¼ä½æ¯new Thread() å建ä¸ä¸ªçº¿ç¨å new Object()è¿æ¯æåºå«çã
new Object()è¿ç¨å¦ä¸ï¼
- JVMåé ä¸åå å M
- å¨å å M ä¸åå§å该对象
- å°å å M çå°åèµå¼ç»å¼ç¨åé obj
å建线ç¨çè¿ç¨å¦ä¸ï¼
- JVM为ä¸ä¸ªçº¿ç¨æ åé å åï¼è¯¥æ 为æ¯ä¸ªçº¿ç¨æ¹æ³è°ç¨ä¿åä¸ä¸ªæ 帧
- æ¯ä¸æ 帧ç±ä¸ä¸ªå±é¨åéæ°ç»ãè¿åå¼ãæä½æ°å æ å叏鿱 ç»æ
- æ¯ä¸ªçº¿ç¨è·å¾ä¸ä¸ªç¨åºè®¡æ°å¨ï¼ç¨äºè®°å½å½åèææºæ£å¨æ§è¡ççº¿ç¨æä»¤å°å
- ç³»ç»å建ä¸ä¸ªä¸Java线ç¨å¯¹åºçæ¬æºçº¿ç¨
- å°ä¸çº¿ç¨ç¸å ³çæè¿°ç¬¦æ·»å å°JVMå 鍿°æ®ç»æä¸
- 线ç¨å ±äº«å åæ¹æ³åºå
å建ä¸ä¸ªçº¿ç¨å¤§æ¦éè¦1Må·¦å³ç空é´ï¼Java8ï¼æºå¨è§æ ¼2c8Gï¼ãå¯è§ï¼é¢ç¹æå¨å建/éæ¯çº¿ç¨ç代价æ¯é常大çã
为ä»ä¹ä½¿ç¨çº¿ç¨æ± ï¼
- éä½èµæºæ¶èãéè¿éå¤å©ç¨å·²å建ç线ç¨éä½çº¿ç¨å建åéæ¯é æçæ¶èã
- æé«ååºé度ãå½ä»»å¡å°è¾¾æ¶ï¼å¯ä»¥ä¸éè¦çå°çº¿ç¨å建就è½ç«å³æ§è¡ã
- æé«çº¿ç¨çå¯ç®¡çæ§ãç»ä¸ç®¡ç线ç¨ï¼é¿å ç³»ç»å建大éå类线ç¨èå¯¼è´æ¶èå®å åã
çº¿ç¨æ± æ§è¡åçï¼

- å½çº¿ç¨æ± éåæ´»ççº¿ç¨æ°å°äºæ ¸å¿çº¿ç¨æ°
corePoolSizeæ¶ï¼è¿æ¶å¯¹äºä¸ä¸ªæ°æäº¤çä»»å¡ï¼çº¿ç¨æ± ä¼å建ä¸ä¸ªçº¿ç¨å»å¤çä»»å¡ãå½çº¿ç¨æ± éé¢åæ´»ççº¿ç¨æ°å°äºçäºæ ¸å¿çº¿ç¨æ°corePoolSizeæ¶ï¼çº¿ç¨æ± éé¢ç线ç¨ä¼ä¸ç´åæ´»çï¼å°±ç®ç©ºé²æ¶é´è¶ è¿äºkeepAliveTimeï¼çº¿ç¨ä¹ä¸ä¼è¢«éæ¯ï¼èæ¯ä¸ç´é»å¡å¨é£éä¸ç´çå¾ ä»»å¡éåç任塿¥æ§è¡ã - å½çº¿ç¨æ± éé¢åæ´»ççº¿ç¨æ°å·²ç»çäºcorePoolSizeäºï¼è¿æ¯å¯¹äºä¸ä¸ªæ°æäº¤çä»»å¡ï¼ä¼è¢«æ¾è¿ä»»å¡éåworkQueueæéçå¾ æ§è¡ã
- å½çº¿ç¨æ± éé¢åæ´»ççº¿ç¨æ°å·²ç»çäº
corePoolSizeäºï¼å¹¶ä¸ä»»å¡éå乿»¡äºï¼å设maximumPoolSize>corePoolSizeï¼è¿æ¶å¦æåæ¥æ°çä»»å¡ï¼çº¿ç¨æ± å°±ä¼ç»§ç»å建æ°ççº¿ç¨æ¥å¤çæ°çä»»å¡ï¼ç¥éçº¿ç¨æ°è¾¾å°maximumPoolSizeï¼å°±ä¸ä¼åå建äºã - 妿å½åççº¿ç¨æ°è¾¾å°äº
maximumPoolSizeï¼å¹¶ä¸ä»»å¡éå乿»¡äºï¼å¦æè¿ææ°çä»»å¡è¿æ¥ï¼é£å°±ç´æ¥éç¨æç»çç¥è¿è¡å¤çãé»è®¤çæç»çç¥æ¯æåºä¸ä¸ªRejectedExecutionExceptionå¼å¸¸ã
çº¿ç¨æ± åæ°æåªäºï¼
ThreadPoolExecutor çéç¨æé 彿°ï¼
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler);
1ãcorePoolSizeï¼å½ææ°ä»»å¡æ¶ï¼å¦æçº¿ç¨æ± ä¸çº¿ç¨æ°æ²¡æè¾¾å°çº¿ç¨æ± çåºæ¬å¤§å°ï¼åä¼å建æ°ççº¿ç¨æ§è¡ä»»å¡ï¼å¦åå°ä»»å¡æ¾å
¥é»å¡éåãå½çº¿ç¨æ± ä¸åæ´»ççº¿ç¨æ°æ»æ¯å¤§äº corePoolSize æ¶ï¼åºè¯¥èèè°å¤§ corePoolSizeã
2ãmaximumPoolSizeï¼å½é»å¡éå填满æ¶ï¼å¦æçº¿ç¨æ± ä¸çº¿ç¨æ°æ²¡æè¶
è¿æå¤§çº¿ç¨æ°ï¼åä¼å建æ°ç线ç¨è¿è¡ä»»å¡ãå¦åæ ¹æ®æç»çç¥å¤çæ°ä»»å¡ãéæ ¸å¿çº¿ç¨ç±»ä¼¼äºä¸´æ¶åæ¥çèµæºï¼è¿äºçº¿ç¨å¨ç©ºé²æ¶é´è¶
è¿ keepAliveTime ä¹åï¼å°±åºè¯¥éåºï¼é¿å
èµæºæµªè´¹ã
3ãBlockingQueueï¼åå¨çå¾
è¿è¡çä»»å¡ã
4ãkeepAliveTimeï¼éæ ¸å¿çº¿ç¨ç©ºé²åï¼ä¿æåæ´»çæ¶é´ï¼æ¤åæ°åªå¯¹éæ ¸å¿çº¿ç¨ææã设置为0ï¼è¡¨ç¤ºå¤ä½ç空é²çº¿ç¨ä¼è¢«ç«å³ç»æ¢ã
5ãTimeUnitï¼æ¶é´åä½
TimeUnit.DAYS
TimeUnit.HOURS
TimeUnit.MINUTES
TimeUnit.SECONDS
TimeUnit.MILLISECONDS
TimeUnit.MICROSECONDS
TimeUnit.NANOSECONDS
6ãThreadFactoryï¼æ¯å½çº¿ç¨æ± å建ä¸ä¸ªæ°ççº¿ç¨æ¶ï¼é½æ¯éè¿çº¿ç¨å·¥åæ¹æ³æ¥å®æçãå¨ ThreadFactory ä¸åªå®ä¹äºä¸ä¸ªæ¹æ³ newThreadï¼æ¯å½çº¿ç¨æ± éè¦å建æ°çº¿ç¨å°±ä¼è°ç¨å®ã
public class MyThreadFactory implements ThreadFactory {
private final String poolName;
public MyThreadFactory(String poolName) {
this.poolName = poolName;
}
public Thread newThread(Runnable runnable) {
return new MyAppThread(runnable, poolName);//å°çº¿ç¨æ± ååä¼ éç»æé 彿°ï¼ç¨äºåºåä¸åçº¿ç¨æ± ç线ç¨
}
}
7ãRejectedExecutionHandlerï¼å½éååçº¿ç¨æ± 齿»¡äºçæ¶åï¼æ ¹æ®æç»çç¥å¤çæ°ä»»å¡ã
AbortPolicyï¼é»è®¤ççç¥ï¼ç´æ¥æåºRejectedExecutionException
DiscardPolicyï¼ä¸å¤çï¼ç´æ¥ä¸¢å¼
DiscardOldestPolicyï¼å°çå¾
éåéé¦çä»»å¡ä¸¢å¼ï¼å¹¶æ§è¡å½åä»»å¡
CallerRunsPolicyï¼ç±è°ç¨çº¿ç¨å¤ç该任å¡
çº¿ç¨æ± 大尿ä¹è®¾ç½®ï¼
å¦æçº¿ç¨æ± çº¿ç¨æ°é太å°ï¼å½æå¤§é请æ±éè¦å¤çï¼ç³»ç»ååºæ¯è¾æ ¢ï¼ä¼å½±åç¨æ·ä½éªï¼çè³ä¼åºç°ä»»å¡éå大éå 积任å¡å¯¼è´OOMã
å¦æçº¿ç¨æ± çº¿ç¨æ°éè¿å¤§ï¼å¤§é线ç¨å¯è½ä¼åæ¶æ¢å CPU èµæºï¼è¿æ ·ä¼å¯¼è´å¤§éçä¸ä¸æåæ¢ï¼ä»èå¢å 线ç¨çæ§è¡æ¶é´ï¼å½±åäºæ§è¡æçã
CPU å¯éåä»»å¡(N+1)ï¼ è¿ç§ä»»å¡æ¶èçä¸»è¦æ¯ CPU èµæºï¼å¯ä»¥å°çº¿ç¨æ°è®¾ç½®ä¸º Nï¼CPU æ ¸å¿æ°ï¼+1ï¼å¤åºæ¥çä¸ä¸ªçº¿ç¨æ¯ä¸ºäºé²æ¢æäºåå 导è´ç线ç¨é»å¡ï¼å¦IOæä½ï¼çº¿ç¨sleepï¼çå¾
éï¼è带æ¥çå½±åã䏿¦æä¸ªçº¿ç¨è¢«é»å¡ï¼éæ¾äºCPUèµæºï¼èå¨è¿ç§æ
åµä¸å¤åºæ¥çä¸ä¸ªçº¿ç¨å°±å¯ä»¥å
åå©ç¨ CPU çç©ºé²æ¶é´ã
I/O å¯éåä»»å¡(2N)ï¼ ç³»ç»ç大é¨åæ¶é´é½å¨å¤ç IO æä½ï¼æ¤æ¶çº¿ç¨å¯è½ä¼è¢«é»å¡ï¼éæ¾CPUèµæºï¼è¿æ¶å°±å¯ä»¥å° CPU 交åºç»å
¶å®çº¿ç¨ä½¿ç¨ãå æ¤å¨ IO å¯éåä»»å¡çåºç¨ä¸ï¼å¯ä»¥å¤é
ç½®ä¸äºçº¿ç¨ï¼å
·ä½çè®¡ç®æ¹æ³ï¼æä½³çº¿ç¨æ° = CPUæ ¸å¿æ° * (1/CPUå©ç¨ç) = CPUæ ¸å¿æ° * (1 + (IOèæ¶/CPUèæ¶))ï¼ä¸è¬å¯è®¾ç½®ä¸º2Nã
çº¿ç¨æ± çç±»åæåªäºï¼éç¨åºæ¯ï¼
常è§ççº¿ç¨æ± æ FixedThreadPoolãSingleThreadExecutorãCachedThreadPool å ScheduledThreadPoolãè¿å ä¸ªé½æ¯ ExecutorService çº¿ç¨æ± å®ä¾ã
FixedThreadPool
åºå®çº¿ç¨æ°ççº¿ç¨æ± ã任使¶é´ç¹ï¼æå¤åªæ nThreads 个线ç¨å¤äºæ´»å¨ç¶ææ§è¡ä»»å¡ã
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
ä½¿ç¨æ çéå LinkedBlockingQueueï¼éå容é为 Integer.MAX_VALUEï¼ï¼è¿è¡ä¸ççº¿ç¨æ± ä¸ä¼æç»ä»»å¡ï¼å³ä¸ä¼è°ç¨RejectedExecutionHandler.rejectedExecution()æ¹æ³ã
maxThreadPoolSize æ¯æ æåæ°ï¼æ å°å®çå¼è®¾ç½®ä¸ºä¸ coreThreadPoolSize ä¸è´ã
keepAliveTime 乿¯æ æåæ°ï¼è®¾ç½®ä¸º0Lï¼å 为æ¤çº¿ç¨æ± éææçº¿ç¨é½æ¯æ ¸å¿çº¿ç¨ï¼æ ¸å¿çº¿ç¨ä¸ä¼è¢«åæ¶ï¼é¤é设置äºexecutor.allowCoreThreadTimeOut(true)ï¼ã
éç¨åºæ¯ï¼éç¨äºå¤çCPUå¯éåçä»»å¡ï¼ç¡®ä¿CPUå¨é¿æè¢«å·¥ä½çº¿ç¨ä½¿ç¨çæ åµä¸ï¼å°½å¯è½çå°çåé 线ç¨ï¼å³éç¨æ§è¡é¿æçä»»å¡ãéè¦æ³¨æçæ¯ï¼FixedThreadPool ä¸ä¼æç»ä»»å¡ï¼å¨ä»»å¡æ¯è¾å¤çæ¶åä¼å¯¼è´ OOMã
SingleThreadExecutor
åªæä¸ä¸ªçº¿ç¨ççº¿ç¨æ± ã
public static ExecutionService newSingleThreadExecutor() {
return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
ä½¿ç¨æ çéå LinkedBlockingQueueãçº¿ç¨æ± åªæä¸ä¸ªè¿è¡ç线ç¨ï¼æ°æ¥ç任塿¾å ¥å·¥ä½éåï¼çº¿ç¨å¤çå®ä»»å¡å°±å¾ªç¯ä»éåéè·å任塿§è¡ãä¿è¯é¡ºåºçæ§è¡å个任å¡ã
éç¨åºæ¯ï¼éç¨äºä¸²è¡æ§è¡ä»»å¡çåºæ¯ï¼ä¸ä¸ªä»»å¡ä¸ä¸ªä»»å¡å°æ§è¡ãå¨ä»»å¡æ¯è¾å¤çæ¶å乿¯ä¼å¯¼è´ OOMã
CachedThreadPool
æ ¹æ®éè¦å建æ°çº¿ç¨ççº¿ç¨æ± ã
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
å¦æä¸»çº¿ç¨æäº¤ä»»å¡çé度é«äºçº¿ç¨å¤çä»»å¡çé度æ¶ï¼CachedThreadPool ä¼ä¸æå建æ°ç线ç¨ãæç«¯æ
åµä¸ï¼è¿æ ·ä¼å¯¼è´èå°½ cpu åå
åèµæºã
ä½¿ç¨æ²¡æå®¹éçSynchronousQueueä½ä¸ºçº¿ç¨æ± å·¥ä½éåï¼å½çº¿ç¨æ± æç©ºé²çº¿ç¨æ¶ï¼SynchronousQueue.offer(Runnable task)æäº¤çä»»å¡ä¼è¢«ç©ºé²çº¿ç¨å¤çï¼å¦åä¼å建æ°ç线ç¨å¤çä»»å¡ã
éç¨åºæ¯ï¼ç¨äºå¹¶åæ§è¡å¤§éçæçå°ä»»å¡ãCachedThreadPoolå
许å建ççº¿ç¨æ°é为 Integer.MAX_VALUE ï¼å¯è½ä¼å建大é线ç¨ï¼ä»èå¯¼è´ OOMã
ScheduledThreadPoolExecutor
å¨ç»å®çå»¶è¿åè¿è¡ä»»å¡ï¼æè
宿æ§è¡ä»»å¡ãå¨å®é
项ç®ä¸åºæ¬ä¸ä¼è¢«ç¨å°ï¼å 为æå
¶ä»æ¹æ¡éæ©æ¯å¦quartzã
使ç¨çä»»å¡éå DelayQueue å°è£
äºä¸ä¸ª PriorityQueueï¼PriorityQueue ä¼å¯¹éåä¸çä»»å¡è¿è¡æåºï¼æ¶é´æ©çä»»å¡å
被æ§è¡(å³ScheduledFutureTask ç time åéå°çå
æ§è¡)ï¼å¦ætimeç¸ååå
æäº¤çä»»å¡ä¼è¢«å
æ§è¡(ScheduledFutureTask ç squenceNumber åéå°çå
æ§è¡)ã
æ§è¡å¨æä»»å¡æ¥éª¤ï¼
- 线ç¨ä»
DelayQueueä¸è·å已尿çScheduledFutureTaskï¼DelayQueue.take()ï¼ã尿任塿¯æScheduledFutureTaskç time 大äºçäºå½åç³»ç»çæ¶é´ï¼ - æ§è¡è¿ä¸ª
ScheduledFutureTaskï¼ - ä¿®æ¹
ScheduledFutureTaskç time åéä¸ºä¸æ¬¡å°è¦è¢«æ§è¡çæ¶é´ï¼ - æè¿ä¸ªä¿®æ¹ time ä¹åç
ScheduledFutureTaskæ¾åDelayQueueä¸ï¼DelayQueue.add())ã

éç¨åºæ¯ï¼å¨ææ§æ§è¡ä»»å¡çåºæ¯ï¼éè¦éå¶çº¿ç¨æ°éçåºæ¯ã
æä¹å¤æçº¿ç¨æ± ç任塿¯ä¸æ¯æ§è¡å®äºï¼
æå ç§æ¹æ³ï¼
1ã使ç¨çº¿ç¨æ± çåç彿°isTerminated();
executoræä¾ä¸ä¸ªåç彿°isTerminated()æ¥å¤æçº¿ç¨æ± ä¸ç任塿¯å¦å ¨é¨å®æãå¦æå ¨é¨å®æè¿åtrueï¼å¦åè¿åfalseã
2ã使ç¨éå ¥éï¼ç»´æä¸ä¸ªå ¬å ±è®¡æ°ã
ææçæ®éä»»å¡ç»´æä¸ä¸ªè®¡æ°å¨ï¼å½ä»»å¡å®ææ¶è®¡æ°å¨å ä¸ï¼è¿éè¦å éï¼ï¼å½è®¡æ°å¨çå¼çäºä»»å¡æ°æ¶ï¼è¿æ¶ææçä»»å¡å·²ç»æ§è¡å®æ¯äºã
3ã使ç¨CountDownLatchã
å®çåçè·ç¬¬äºç§æ¹æ³ç±»ä¼¼ï¼ç»CountDownLatchä¸ä¸ªè®¡æ°å¼ï¼ä»»å¡æ§è¡å®æ¯åï¼è°ç¨countDown()æ§è¡è®¡æ°å¼åä¸ãæåæ§è¡çä»»å¡å¨è°ç¨æ¹æ³çå¼å§è°ç¨await()æ¹æ³ï¼è¿æ ·æ´ä¸ªä»»å¡ä¼é»å¡ï¼ç´å°è¿ä¸ªè®¡æ°å¼ä¸ºé¶ï¼æä¼ç»§ç»æ§è¡ã
è¿ç§æ¹å¼ç缺ç¹å°±æ¯éè¦æåç¥éä»»å¡çæ°éã
4ãsubmitåçº¿ç¨æ± æäº¤ä»»å¡ï¼ä½¿ç¨Future夿任塿§è¡ç¶æã
使ç¨submitåçº¿ç¨æ± æäº¤ä»»å¡ä¸executeæäº¤ä¸åï¼submit伿Futureç±»åçè¿åå¼ãéè¿future.isDone()æ¹æ³å¯ä»¥ç¥é任塿¯å¦æ§è¡å®æã
为ä»ä¹è¦ä½¿ç¨Executorçº¿ç¨æ± æ¡æ¶å¢ï¼
- æ¯æ¬¡æ§è¡ä»»å¡é½éè¿new Thread()å»å建线ç¨ï¼æ¯è¾æ¶èæ§è½ï¼å建ä¸ä¸ªçº¿ç¨æ¯æ¯è¾èæ¶ãèèµæºç
- è°ç¨new Thread()å建ç线ç¨ç¼ºä¹ç®¡çï¼å¯ä»¥æ éå¶çå建ï¼çº¿ç¨ä¹é´çç¸äºç«äºä¼å¯¼è´è¿å¤å ç¨ç³»ç»èµæºè导è´ç³»ç»ç«çª
- ç´æ¥ä½¿ç¨new Thread()å¯å¨ç线ç¨ä¸å©äºæ©å±ï¼æ¯å¦å®æ¶æ§è¡ã宿æ§è¡ã宿¶å®ææ§è¡ã线ç¨ä¸æçé½ä¸å¥½å®ç°
executeåsubmitçåºå«
executeåªè½æäº¤Runnableç±»åçä»»å¡ï¼æ è¿åå¼ãsubmitæ¢å¯ä»¥æäº¤Runnableç±»åçä»»å¡ï¼ä¹å¯ä»¥æäº¤Callableç±»åçä»»å¡ï¼ä¼æä¸ä¸ªç±»å为Futureçè¿åå¼ï¼ä½å½ä»»å¡ç±»å为Runnableæ¶ï¼è¿åå¼ä¸ºnullã
execute卿§è¡ä»»å¡æ¶ï¼å¦æéå°å¼å¸¸ä¼ç´æ¥æåºï¼èsubmitä¸ä¼ç´æ¥æåºï¼åªæå¨ä½¿ç¨Futureçgetæ¹æ³è·åè¿å弿¶ï¼æä¼æåºå¼å¸¸
executeæå±é¡¶å±æ¥å£æ¯Executorï¼submitæå±é¡¶å±æ¥å£æ¯ExecutorServiceï¼å®ç°ç±»ThreadPoolExecutoréåäºexecuteæ¹æ³ï¼æ½è±¡ç±»AbstractExecutorServiceéåäºsubmitæ¹æ³ã
è¿ç¨çº¿ç¨
è¿ç¨æ¯æä¸ä¸ªå åä¸è¿è¡çåºç¨ç¨åºï¼æ¯ä¸ªè¿ç¨é½æèªå·±ç¬ç«çä¸åå å空é´ã
çº¿ç¨æ¯æ¯è¿ç¨æ´å°çæ§è¡åä½ï¼å®æ¯å¨ä¸ä¸ªè¿ç¨ä¸ç¬ç«çæ§å¶æµï¼ä¸ä¸ªè¿ç¨å¯ä»¥å¯å¨å¤ä¸ªçº¿ç¨ï¼æ¯æ¡çº¿ç¨å¹¶è¡æ§è¡ä¸åçä»»å¡ã
线ç¨ççå½å¨æ
åå§(NEW)ï¼çº¿ç¨è¢«æå»ºï¼è¿æ²¡æè°ç¨ start()ã
è¿è¡(RUNNABLE)ï¼å æ¬æä½ç³»ç»ç就绪åè¿è¡ä¸¤ç§ç¶æã
é»å¡(BLOCKED)ï¼ä¸è¬æ¯è¢«å¨çï¼å¨æ¢å èµæºä¸å¾ä¸å°èµæºï¼è¢«å¨çæèµ·å¨å åï¼çå¾ èµæºéæ¾å°å ¶å¤éã线ç¨è¢«é»å¡ä¼éæ¾CPUï¼ä¸éæ¾å åã
çå¾ (WAITING)ï¼è¿å ¥è¯¥ç¶æç线ç¨éè¦çå¾ å ¶ä»çº¿ç¨ååºä¸äºç¹å®å¨ä½ï¼éç¥æä¸æï¼ã
è¶ æ¶çå¾ (TIMED_WAITING)ï¼è¯¥ç¶æä¸åäºWAITINGï¼å®å¯ä»¥å¨æå®çæ¶é´åèªè¡è¿åã
ç»æ¢(TERMINATED)ï¼è¡¨ç¤ºè¯¥çº¿ç¨å·²ç»æ§è¡å®æ¯ã

å¾çæ¥æºï¼Javaå¹¶åç¼ç¨çèºæ¯
讲讲线ç¨ä¸æï¼
线ç¨ä¸æå³çº¿ç¨è¿è¡è¿ç¨ä¸è¢«å ¶ä»çº¿ç¨ç»ææäºï¼å®ä¸ stop æå¤§çåºå«æ¯ï¼stop æ¯ç±ç³»ç»å¼ºå¶ç»æ¢çº¿ç¨ï¼è线ç¨ä¸æåæ¯ç»ç®æ 线ç¨åéä¸ä¸ªä¸æä¿¡å·ï¼å¦æç®æ çº¿ç¨æ²¡ææ¥æ¶çº¿ç¨ä¸æçä¿¡å·å¹¶ç»æçº¿ç¨ï¼çº¿ç¨åä¸ä¼ç»æ¢ï¼å ·ä½æ¯å¦éåºæè æ§è¡å ¶ä»é»è¾åå³äºç®æ 线ç¨ã
线ç¨ä¸æä¸ä¸ªéè¦çæ¹æ³ï¼
1ãjava.lang.Thread#interrupt
è°ç¨ç®æ 线ç¨çinterrupt()æ¹æ³ï¼ç»ç®æ 线ç¨åä¸ä¸ªä¸æä¿¡å·ï¼çº¿ç¨è¢«æä¸ä¸ææ è®°ã
2ãjava.lang.Thread#isInterrupted()
å¤æç®æ çº¿ç¨æ¯å¦è¢«ä¸æï¼ä¸ä¼æ¸ é¤ä¸ææ è®°ã
3ãjava.lang.Thread#interrupted
å¤æç®æ çº¿ç¨æ¯å¦è¢«ä¸æï¼ä¼æ¸ é¤ä¸ææ è®°ã
private static void test2() {
Thread thread = new Thread(() -> {
while (true) {
Thread.yield();
// ååºä¸æ
if (Thread.currentThread().isInterrupted()) {
System.out.println("Javaææ¯æ 线ç¨è¢«ä¸æï¼ç¨åºéåºã");
return;
}
}
});
thread.start();
thread.interrupt();
}
åå»ºçº¿ç¨æåªå ç§æ¹å¼ï¼
- éè¿æ©å±
Threadç±»æ¥å建å¤çº¿ç¨ - éè¿å®ç°
Runnableæ¥å£æ¥å建å¤çº¿ç¨ - å®ç°
Callableæ¥å£ï¼éè¿FutureTaskæ¥å£å建线ç¨ã - 使ç¨
Executoræ¡æ¶æ¥åå»ºçº¿ç¨æ± ã
ç»§æ¿ Thread å建线ç¨ä»£ç å¦ä¸ãrun()æ¹æ³æ¯ç±jvmåå»ºå®æä½ç³»ç»çº§çº¿ç¨ååè°çæ¹æ³ï¼ä¸å¯ä»¥æå¨è°ç¨ï¼æå¨è°ç¨ç¸å½äºè°ç¨æ®éæ¹æ³ã
/**
* @author: ç¨åºå大彬
* @time: 2021-09-11 10:15
*/
public class MyThread extends Thread {
public MyThread() {
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread() + ":" + i);
}
}
public static void main(String[] args) {
MyThread mThread1 = new MyThread();
MyThread mThread2 = new MyThread();
MyThread myThread3 = new MyThread();
mThread1.start();
mThread2.start();
myThread3.start();
}
}
Runnable å建线ç¨ä»£ç ï¼
/**
* @author: ç¨åºå大彬
* @time: 2021-09-11 10:04
*/
public class RunnableTest {
public static void main(String[] args){
Runnable1 r = new Runnable1();
Thread thread = new Thread(r);
thread.start();
System.out.println("主线ç¨ï¼["+Thread.currentThread().getName()+"]");
}
}
class Runnable1 implements Runnable{
@Override
public void run() {
System.out.println("å½å线ç¨ï¼"+Thread.currentThread().getName());
}
}
å®ç°Runnableæ¥å£æ¯ç»§æ¿Threadç±»æå ·æçä¼å¿ï¼
- å¯ä»¥é¿å javaä¸çåç»§æ¿çéå¶
- çº¿ç¨æ± åªè½æ¾å ¥å®ç°RunableæCallable类线ç¨ï¼ä¸è½ç´æ¥æ¾å ¥ç»§æ¿Threadçç±»
Callable å建线ç¨ä»£ç ï¼
/**
* @author: ç¨åºå大彬
* @time: 2021-09-11 10:21
*/
public class CallableTest {
public static void main(String[] args) {
Callable1 c = new Callable1();
//弿¥è®¡ç®çç»æ
FutureTask<Integer> result = new FutureTask<>(c);
new Thread(result).start();
try {
//çå¾
ä»»å¡å®æï¼è¿åç»æ
int sum = result.get();
System.out.println(sum);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
class Callable1 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
return sum;
}
}
ä½¿ç¨ Executor å建线ç¨ä»£ç ï¼
/**
* @author: ç¨åºå大彬
* @time: 2021-09-11 10:44
*/
public class ExecutorsTest {
public static void main(String[] args) {
//è·åExecutorServiceå®ä¾ï¼ç产ç¦ç¨ï¼éè¦æå¨åå»ºçº¿ç¨æ±
ExecutorService executorService = Executors.newCachedThreadPool();
//æäº¤ä»»å¡
executorService.submit(new RunnableDemo());
}
}
class RunnableDemo implements Runnable {
@Override
public void run() {
System.out.println("大彬");
}
}
ä»ä¹æ¯çº¿ç¨æ»éï¼
çº¿ç¨æ»éæ¯æä¸¤ä¸ªæä¸¤ä¸ªä»¥ä¸ç线ç¨å¨æ§è¡è¿ç¨ä¸ï¼å äºå¤ºèµæºèé æçä¸ç§äºç¸çå¾ çç°è±¡ãè¥æ å¤åä½ç¨ï¼å®ä»¬é½å°æ æ³æ¨è¿ä¸å»ã
å¦ä¸å¾æç¤ºï¼çº¿ç¨ A ææèµæº 2ï¼çº¿ç¨ B ææèµæº 1ï¼ä»ä»¬åæ¶é½æ³ç³è¯·å¯¹æ¹ææçèµæºï¼æä»¥è¿ä¸¤ä¸ªçº¿ç¨å°±ä¼äºç¸çå¾ èè¿å ¥æ»éç¶æã

ä¸é¢éè¿ä¾å说æçº¿ç¨æ»éï¼ä»£ç æ¥èªå¹¶åç¼ç¨ä¹ç¾ã
public class DeadLockDemo {
private static Object resource1 = new Object();//èµæº 1
private static Object resource2 = new Object();//èµæº 2
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "çº¿ç¨ 1").start();
new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}, "çº¿ç¨ 2").start();
}
}
代ç è¾åºå¦ä¸ï¼
Thread[çº¿ç¨ 1,5,main]get resource1
Thread[çº¿ç¨ 2,5,main]get resource2
Thread[çº¿ç¨ 1,5,main]waiting get resource2
Thread[çº¿ç¨ 2,5,main]waiting get resource1
çº¿ç¨ A éè¿ synchronized (resource1) è·å¾ resource1 ççè§å¨éï¼ç¶åéè¿ Thread.sleep(1000)ãè®©çº¿ç¨ A ä¼ç 1s ä¸ºçæ¯è®©çº¿ç¨ B å¾å°æ§è¡ç¶åè·åå° resource2 ççè§å¨éãçº¿ç¨ A åçº¿ç¨ B ä¼ç ç»æäºé½å¼å§ä¼å¾è¯·æ±è·å对æ¹çèµæºï¼ç¶åè¿ä¸¤ä¸ªçº¿ç¨å°±ä¼é·å
¥äºç¸çå¾
çç¶æï¼è¿ä¹å°±äº§çäºæ»éã
çº¿ç¨æ»éæä¹äº§çï¼æä¹é¿å ï¼
æ»é产ççåä¸ªå¿ è¦æ¡ä»¶ï¼
äºæ¥ï¼ä¸ä¸ªèµæºæ¯æ¬¡åªè½è¢«ä¸ä¸ªè¿ç¨ä½¿ç¨
请æ±ä¸ä¿æï¼ä¸ä¸ªè¿ç¨å 请æ±èµæºèé»å¡æ¶ï¼ä¸éæ¾è·å¾çèµæº
ä¸å¥å¤ºï¼è¿ç¨å·²è·å¾çèµæºï¼å¨æªä½¿ç¨ä¹åï¼ä¸è½å¼ºè¡å¥å¤º
循ç¯çå¾ ï¼è¿ç¨ä¹é´å¾ªç¯çå¾ çèµæº
é¿å æ»éçæ¹æ³ï¼
- äºæ¥æ¡ä»¶ä¸è½ç ´åï¼å 为å éå°±æ¯ä¸ºäºä¿è¯äºæ¥
- 䏿¬¡æ§ç³è¯·ææçèµæºï¼é¿å 线ç¨å æèµæºèä¸å¨çå¾ å ¶ä»èµæº
- å æé¨åèµæºç线ç¨è¿ä¸æ¥ç³è¯·å ¶ä»èµæºæ¶ï¼å¦æç³è¯·ä¸å°ï¼ä¸»å¨éæ¾å®å æçèµæº
- æåºç³è¯·èµæº
线ç¨runåstartçåºå«ï¼
- å½ç¨åºè°ç¨
start()æ¹æ³ï¼å°ä¼å建ä¸ä¸ªæ°çº¿ç¨å»æ§è¡run()æ¹æ³ä¸ç代ç ãrun()å°±åä¸ä¸ªæ®éæ¹æ³ä¸æ ·ï¼ç´æ¥è°ç¨run()çè¯ï¼ä¸ä¼å建æ°çº¿ç¨ã - ä¸ä¸ªçº¿ç¨ç
start()æ¹æ³åªè½è°ç¨ä¸æ¬¡ï¼å¤æ¬¡è°ç¨ä¼æåº java.lang.IllegalThreadStateException å¼å¸¸ãrun()æ¹æ³å没æéå¶ã
线ç¨é½æåªäºæ¹æ³ï¼
start
ç¨äºå¯å¨çº¿ç¨ã
getPriority
è·å线ç¨ä¼å 级ï¼é»è®¤æ¯5ï¼çº¿ç¨é»è®¤ä¼å 级为5ï¼å¦æä¸æå¨æå®ï¼é£ä¹çº¿ç¨ä¼å çº§å ·æç»§æ¿æ§ï¼æ¯å¦çº¿ç¨Aå¯å¨çº¿ç¨Bï¼é£ä¹çº¿ç¨Bçä¼å 级å线ç¨Açä¼å 级ç¸å
setPriority
设置线ç¨ä¼å 级ãCPUä¼å°½éå°æ§è¡èµæºè®©ç»ä¼å 级æ¯è¾é«ç线ç¨ã
interrupt
åè¯çº¿ç¨ï¼ä½ åºè¯¥ä¸æäºï¼å ·ä½å°åºä¸æè¿æ¯ç»§ç»è¿è¡ï¼ç±è¢«éç¥ç线ç¨èªå·±å¤çã
å½å¯¹ä¸ä¸ªçº¿ç¨è°ç¨ interrupt() æ¶ï¼æä¸¤ç§æ åµï¼
å¦æçº¿ç¨å¤äºè¢«é»å¡ç¶æï¼ä¾å¦å¤äºsleep, wait, join çç¶æï¼ï¼é£ä¹çº¿ç¨å°ç«å³éåºè¢«é»å¡ç¶æï¼å¹¶æåºä¸ä¸ªInterruptedExceptionå¼å¸¸ã
å¦æçº¿ç¨å¤äºæ£å¸¸æ´»å¨ç¶æï¼é£ä¹ä¼å°è¯¥çº¿ç¨ç䏿æ å¿è®¾ç½®ä¸º trueãä¸è¿ï¼è¢«è®¾ç½®ä¸ææ å¿ç线ç¨å¯ä»¥ç»§ç»æ£å¸¸è¿è¡ï¼ä¸åå½±åã
interrupt() å¹¶ä¸è½çæ£çä¸æçº¿ç¨ï¼éè¦è¢«è°ç¨ç线ç¨èªå·±è¿è¡é åæè¡ã
join
çå¾ å ¶ä»çº¿ç¨ç»æ¢ãå¨å½å线ç¨ä¸è°ç¨å¦ä¸ä¸ªçº¿ç¨çjoin()æ¹æ³ï¼åå½å线ç¨è½¬å ¥é»å¡ç¶æï¼ç´å°å¦ä¸ä¸ªè¿ç¨è¿è¡ç»æï¼å½å线ç¨åç±é»å¡è½¬ä¸ºå°±ç»ªç¶æã
yield
æåå½åæ£å¨æ§è¡ç线ç¨å¯¹è±¡ï¼ææ§è¡æºä¼è®©ç»ç¸åæè æ´é«ä¼å 级ç线ç¨ã
sleep
使线ç¨è½¬å°é»å¡ç¶æãmillisåæ°è®¾å®ç¡ç çæ¶é´ï¼ä»¥æ¯«ç§ä¸ºåä½ãå½ç¡ç ç»æåï¼çº¿ç¨èªå¨è½¬ä¸ºRunnableç¶æã
å¦ä½åæ¢ä¸ä¸ªæ£å¨è¿è¡ç线ç¨ï¼
- 使ç¨å ±äº«åéçæ¹å¼ãå ±äº«åéå¯ä»¥è¢«å¤ä¸ªæ§è¡ç¸åä»»å¡ç线ç¨ç¨æ¥ä½ä¸ºæ¯å¦åæ¢çä¿¡å·ï¼éç¥åæ¢çº¿ç¨çæ§è¡ã
- 使ç¨interruptæ¹æ³ç»æ¢çº¿ç¨ãå½ä¸ä¸ªçº¿ç¨è¢«é»å¡ï¼å¤äºä¸å¯è¿è¡ç¶ææ¶ï¼å³ä½¿ä¸»ç¨åºä¸å°è¯¥çº¿ç¨çå ±äº«åé设置为trueï¼ä½è¯¥çº¿ç¨æ¤æ¶æ ¹æ¬æ æ³æ£æ¥å¾ªç¯æ å¿ï¼å½ç¶ä¹å°±æ æ³ç«å³ä¸æãè¿æ¶åå¯ä»¥ä½¿ç¨Threadæä¾çinterrupt()æ¹æ³ï¼å ä¸ºè¯¥æ¹æ³è½ç¶ä¸ä¼ä¸æä¸ä¸ªæ£å¨è¿è¡ç线ç¨ï¼ä½æ¯å®å¯ä»¥ä½¿ä¸ä¸ªè¢«é»å¡ççº¿ç¨æåºä¸ä¸ªä¸æå¼å¸¸ï¼ä»èä½¿çº¿ç¨æåç»æé»å¡ç¶æã
volatileåºå±åç
volatileæ¯è½»é级ç忥æºå¶ï¼volatileä¿è¯åé对ææçº¿ç¨çå¯è§æ§ï¼ä¸ä¿è¯ååæ§ã
- å½å¯¹
volatileåéè¿è¡åæä½çæ¶åï¼JVMä¼åå¤çå¨åé䏿¡LOCKåç¼çæä»¤ï¼å°è¯¥åéæå¨ç¼åè¡çæ°æ®ååç³»ç»å åã - ç±äºç¼åä¸è´æ§åè®®ï¼æ¯ä¸ªå¤çå¨éè¿å æ¢å¨æ»çº¿ä¸ä¼ æçæ°æ®æ¥æ£æ¥èªå·±çç¼åæ¯ä¸æ¯è¿æäºï¼å½å¤çå¨åç°èªå·±ç¼åè¡å¯¹åºçå åå°å被修æ¹ï¼å°±ä¼å°å½åå¤çå¨çç¼åè¡ç½®ä¸ºæ æç¶æï¼å½å¤çå¨å¯¹è¿ä¸ªæ°æ®è¿è¡ä¿®æ¹æä½çæ¶åï¼ä¼éæ°ä»ç³»ç»å åä¸ææ°æ®è¯»å°å¤çå¨ç¼åä¸ã
æ¥ççç¼åä¸è´æ§åè®®æ¯ä»ä¹ã
ç¼åä¸è´æ§åè®®ï¼å½CPUåæ°æ®æ¶ï¼å¦æåç°æä½çåéæ¯å ±äº«åéï¼å³å¨å ¶ä»CPUä¸ä¹åå¨è¯¥åéç坿¬ï¼ä¼ååºä¿¡å·éç¥å ¶ä»CPUå°è¯¥åéçç¼åè¡ç½®ä¸ºæ æç¶æï¼å æ¤å½å ¶ä»CPUéè¦è¯»åè¿ä¸ªåéæ¶ï¼å°±ä¼ä»å åéæ°è¯»åã
volatileå
³é®åç两个ä½ç¨ï¼
- ä¿è¯äºä¸å线ç¨å¯¹å ±äº«åéè¿è¡æä½æ¶çå¯è§æ§ï¼å³ä¸ä¸ªçº¿ç¨ä¿®æ¹äºæä¸ªåéçå¼ï¼è¿æ°å¼å¯¹å ¶ä»çº¿ç¨æ¥è¯´æ¯ç«å³å¯è§çã
- ç¦æ¢è¿è¡æä»¤éæåºã
æä»¤éæåºæ¯JVM为äºä¼åæä»¤ï¼æé«ç¨åºè¿è¡æçï¼å¨ä¸å½±åå线ç¨ç¨åºæ§è¡ç»æçåæä¸ï¼å°½å¯è½å°æé«å¹¶è¡åº¦ãJavaç¼è¯å¨ä¼å¨çææä»¤ç³»åæ¶å¨éå½çä½ç½®ä¼æå ¥
å åå±éæä»¤æ¥ç¦æ¢å¤çå¨éæåºãæå ¥ä¸ä¸ªå åå±éï¼ç¸å½äºåè¯CPUåç¼è¯å¨å äºè¿ä¸ªå½ä»¤çå¿ é¡»å æ§è¡ï¼åäºè¿ä¸ªå½ä»¤çå¿ é¡»åæ§è¡ã对ä¸ä¸ªvolatileåæ®µè¿è¡åæä½ï¼Javaå 忍¡åå°å¨åæä½åæå ¥ä¸ä¸ªåå±éæä»¤ï¼è¿ä¸ªæä»¤ä¼æä¹åçåå ¥å¼é½å·æ°å°å åã
volatile为ä»ä¹ä¸è½ä¿è¯ååæ§ï¼
volatileå¯ä»¥ä¿è¯å¯è§æ§åé¡ºåºæ§ï¼ä½æ¯å®ä¸è½ä¿è¯ååæ§ã
举个ä¾åãä¸ä¸ªåéi被volatile修饰ï¼ä¸¤ä¸ªçº¿ç¨æ³å¯¹è¿ä¸ªåéä¿®æ¹ï¼é½å¯¹å ¶è¿è¡èªå¢æä½i++ï¼i++çè¿ç¨å¯ä»¥åä¸ºä¸æ¥ï¼é¦å è·åiçå¼ï¼å ¶æ¬¡å¯¹içå¼è¿è¡å 1ï¼æåå°å¾å°çæ°å¼åä¼å°ç¼åä¸ã
åå¦içåå§å¼ä¸º100ã线ç¨Aé¦å å¾å°äºiçåå§å¼100ï¼ä½æ¯è¿æ²¡æ¥å¾åä¿®æ¹ï¼å°±é»å¡äºï¼è¿æ¶çº¿ç¨Bå¼å§äºï¼å®ä¹å»åiçå¼ï¼ç±äºiç弿ªè¢«ä¿®æ¹ï¼å³ä½¿æ¯è¢«volatile修饰ï¼ä¸»åçåéè¿æ²¡ååï¼é£ä¹çº¿ç¨Bå¾å°çå¼ä¹æ¯100ï¼ä¹åå¯¹å ¶è¿è¡å 1æä½ï¼å¾å°101ï¼å°æ°å¼åå ¥å°ç¼åä¸ï¼åå·å ¥ä¸»åä¸ãæ ¹æ®å¯è§æ§çååï¼è¿ä¸ªä¸»åçå¼å¯ä»¥è¢«å ¶ä»çº¿ç¨å¯è§ã
é£ä¹é®é¢æ¥äºï¼çº¿ç¨Aä¹åå·²ç»è¯»åå°äºiçå¼ä¸º100ï¼çº¿ç¨Aé»å¡ç»æåï¼ç»§ç»å°100è¿ä¸ªå¼å 1ï¼å¾å°101ï¼åå°å¼åå°ç¼åï¼æåå·å ¥ä¸»åãè¿æ ·iç»è¿ä¸¤æ¬¡èªå¢ä¹åï¼ç»æå¼åªå äº1ï¼ææ¾æ¯æé®é¢çãæä»¥è¯´å³ä¾¿volatileå ·æå¯è§æ§ï¼ä¹ä¸è½ä¿è¯å¯¹å®ä¿®é¥°çåéå ·æååæ§ã
synchronizedçç¨æ³æåªäº?
- 修饰æ®éæ¹æ³ï¼ä½ç¨äºå½å对象å®ä¾ï¼è¿å ¥åæ¥ä»£ç åè¦è·å¾å½å对象å®ä¾çé
- ä¿®é¥°éææ¹æ³ï¼ä½ç¨äºå½åç±»ï¼è¿å ¥åæ¥ä»£ç åè¦è·å¾å½å类对象çéï¼synchronizedå ³é®åå å°static éææ¹æ³å synchronized(class)代ç åä¸é½æ¯æ¯ç» Class ç±»ä¸é
- 修饰代ç åï¼æå®å é对象ï¼å¯¹ç»å®å¯¹è±¡å éï¼è¿å ¥åæ¥ä»£ç åºåè¦è·å¾ç»å®å¯¹è±¡çé
synchronizedçä½ç¨æåªäºï¼
ååæ§ï¼ç¡®ä¿çº¿ç¨äºæ¥ç访é®åæ¥ä»£ç ï¼
å¯è§æ§ï¼ä¿è¯å ±äº«åéçä¿®æ¹è½å¤åæ¶å¯è§ï¼
æåºæ§ï¼ææè§£å³éæåºé®é¢ã
synchronized åºå±å®ç°åçï¼
synchronized 忥代ç åçå®ç°æ¯éè¿ monitorenter å monitorexit æä»¤ï¼å
¶ä¸ monitorenter æä»¤æå忥代ç åçå¼å§ä½ç½®ï¼monitorexit æä»¤åææåæ¥ä»£ç åçç»æä½ç½®ã彿§è¡ monitorenter æä»¤æ¶ï¼çº¿ç¨è¯å¾è·åéä¹å°±æ¯è·å monitorçæææï¼monitor对象åå¨äºæ¯ä¸ªJava对象ç对象头ä¸ï¼ synchronized é便æ¯éè¿è¿ç§æ¹å¼è·åéçï¼ä¹æ¯ä¸ºä»ä¹Javaä¸ä»»æå¯¹è±¡å¯ä»¥ä½ä¸ºéçåå ï¼ã
å
¶å
é¨å
å«ä¸ä¸ªè®¡æ°å¨ï¼å½è®¡æ°å¨ä¸º0åå¯ä»¥æåè·åï¼è·ååå°é计æ°å¨è®¾ä¸º1ä¹å°±æ¯å 1ãç¸åºç卿§è¡ monitorexit æä»¤åï¼å°é计æ°å¨è®¾ä¸º0 ï¼è¡¨æéè¢«éæ¾ã妿è·å对象é失败ï¼é£å½å线ç¨å°±è¦é»å¡çå¾
ï¼ç´å°é被å¦å¤ä¸ä¸ªçº¿ç¨éæ¾ä¸ºæ¢
synchronized ä¿®é¥°çæ¹æ³å¹¶æ²¡æ monitorenter æä»¤å monitorexit æä»¤ï¼åå¾ä»£ä¹çç¡®å®æ¯ACC_SYNCHRONIZED æ è¯ï¼è¯¥æ è¯ææäºè¯¥æ¹æ³æ¯ä¸ä¸ªåæ¥æ¹æ³ï¼JVM éè¿è¯¥ ACC_SYNCHRONIZED è®¿é®æ å¿æ¥è¾¨å«ä¸ä¸ªæ¹æ³æ¯å¦å£°æä¸ºåæ¥æ¹æ³ï¼ä»èæ§è¡ç¸åºç忥è°ç¨ã
volatileåsynchronizedçåºå«æ¯ä»ä¹ï¼
volatileåªè½ä½¿ç¨å¨åéä¸ï¼èsynchronizedå¯ä»¥å¨ç±»ï¼åéï¼æ¹æ³å代ç åä¸ãvolatileè³ä¿è¯å¯è§æ§ï¼synchronizedä¿è¯ååæ§ä¸å¯è§æ§ãvolatileç¦ç¨æä»¤éæåºï¼synchronizedä¸ä¼ãvolatileä¸ä¼é æé»å¡ï¼synchronizedä¼ã
ReentrantLockåsynchronizedåºå«
- 使ç¨synchronizedå ³é®åå®ç°åæ¥ï¼çº¿ç¨æ§è¡å®åæ¥ä»£ç åä¼èªå¨éæ¾éï¼èReentrantLockéè¦æå¨éæ¾éã
- synchronizedæ¯éå ¬å¹³éï¼ReentrantLockå¯ä»¥è®¾ç½®ä¸ºå ¬å¹³éã
- ReentrantLockä¸çå¾ è·åéççº¿ç¨æ¯å¯ä¸æçï¼çº¿ç¨å¯ä»¥æ¾å¼çå¾ éãèsynchonized伿 éæçå¾ ä¸å»ã
- ReentrantLock å¯ä»¥è®¾ç½®è¶ æ¶è·åéã卿å®çæªæ¢æ¶é´ä¹åè·åéï¼å¦ææªæ¢æ¶é´å°äºè¿æ²¡æè·åå°éï¼åè¿åã
- ReentrantLock ç tryLock() æ¹æ³å¯ä»¥å°è¯éé»å¡çè·åéï¼è°ç¨è¯¥æ¹æ³åç«å»è¿åï¼å¦æè½å¤è·ååè¿åtrueï¼å¦åè¿åfalseã
wait()åsleep()çå¼åç¹ï¼
ç¸åç¹ï¼
- å®ä»¬é½å¯ä»¥ä½¿å½åçº¿ç¨æåè¿è¡ï¼ææºä¼äº¤ç»å ¶ä»çº¿ç¨
- ä»»ä½çº¿ç¨å¨è°ç¨wait()åsleep()ä¹åï¼å¨çå¾
æé´è¢«ä¸æé½ä¼æåº
InterruptedException
ä¸åç¹ï¼
wait()æ¯Objectè¶ ç±»ä¸çæ¹æ³ï¼èsleep()æ¯çº¿ç¨Threadç±»ä¸çæ¹æ³- 对éçææä¸åï¼
wait()ä¼éæ¾éï¼èsleep()å¹¶ä¸éæ¾é - å¤éæ¹æ³ä¸å®å
¨ç¸åï¼
wait()ä¾énotifyæènotifyAllã䏿ãè¾¾å°æå®æ¶é´æ¥å¤éï¼èsleep()å°è¾¾æå®æ¶é´è¢«å¤é - è°ç¨
wait()éè¦å è·å对象çéï¼èThread.sleep()ä¸ç¨
RunnableåCallableæä»ä¹åºå«ï¼
- Callableæ¥å£æ¹æ³æ¯
call()ï¼Runnableçæ¹æ³æ¯run()ï¼ - Callableæ¥å£callæ¹æ³æè¿åå¼ï¼æ¯ææ³åï¼Runnableæ¥å£runæ¹æ³æ è¿åå¼ã
- Callableæ¥å£
call()æ¹æ³å 许æåºå¼å¸¸ï¼èRunnableæ¥å£run()æ¹æ³ä¸è½ç»§ç»ä¸æå¼å¸¸ã
çº¿ç¨æ§è¡é¡ºåºæä¹æ§å¶ï¼
å设æT1ãT2ãT3ä¸ä¸ªçº¿ç¨ï¼ä½ ææ ·ä¿è¯T2å¨T1æ§è¡å®åæ§è¡ï¼T3å¨T2æ§è¡å®åæ§è¡ï¼
å¯ä»¥ä½¿ç¨joinæ¹æ³è§£å³è¿ä¸ªé®é¢ãæ¯å¦å¨çº¿ç¨Aä¸ï¼è°ç¨çº¿ç¨Bçjoinæ¹æ³è¡¨ç¤ºçææå°±æ¯**ï¼Açå¾ Bçº¿ç¨æ§è¡å®æ¯åï¼éæ¾CPUæ§è¡æï¼ï¼å¨ç»§ç»æ§è¡ã**
代ç å¦ä¸ï¼
public class ThreadTest {
public static void main(String[] args) {
Thread spring = new Thread(new SeasonThreadTask("æ¥å¤©"));
Thread summer = new Thread(new SeasonThreadTask("å¤å¤©"));
Thread autumn = new Thread(new SeasonThreadTask("ç§å¤©"));
try
{
//æ¥å¤©çº¿ç¨å
å¯å¨
spring.start();
//主线ç¨çå¾
线ç¨springæ§è¡å®ï¼åå¾ä¸æ§è¡
spring.join();
//å¤å¤©çº¿ç¨åå¯å¨
summer.start();
//主线ç¨çå¾
线ç¨summeræ§è¡å®ï¼åå¾ä¸æ§è¡
summer.join();
//ç§å¤©çº¿ç¨æåå¯å¨
autumn.start();
//主线ç¨çå¾
线ç¨autumnæ§è¡å®ï¼åå¾ä¸æ§è¡
autumn.join();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
class SeasonThreadTask implements Runnable{
private String name;
public SeasonThreadTask(String name){
this.name = name;
}
@Override
public void run() {
for (int i = 1; i <4; i++) {
System.out.println(this.name + "æ¥äº: " + i + "次");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
è¿è¡ç»æï¼
æ¥å¤©æ¥äº: 1次
æ¥å¤©æ¥äº: 2次
æ¥å¤©æ¥äº: 3次
å¤å¤©æ¥äº: 1次
å¤å¤©æ¥äº: 2次
å¤å¤©æ¥äº: 3次
ç§å¤©æ¥äº: 1次
ç§å¤©æ¥äº: 2次
ç§å¤©æ¥äº: 3次
宿¤çº¿ç¨æ¯ä»ä¹ï¼
宿¤çº¿ç¨æ¯è¿è¡å¨åå°çä¸ç§ç¹æ®è¿ç¨ãå®ç¬ç«äºæ§å¶ç»ç«¯å¹¶ä¸å¨ææ§å°æ§è¡æç§ä»»å¡æçå¾ å¤çæäºåççäºä»¶ãå¨ Java ä¸åå¾åæ¶çº¿ç¨å°±æ¯ç¹æ®ç宿¤çº¿ç¨ã
线ç¨é´éä¿¡æ¹å¼
1ãä½¿ç¨ Object ç±»ç wait()/notify()ãObject ç±»æä¾äºçº¿ç¨é´éä¿¡çæ¹æ³ï¼wait()ãnotify()ãnotifyAll()ï¼å®ä»¬æ¯å¤çº¿ç¨éä¿¡çåºç¡ãå
¶ä¸ï¼wait/notify å¿
é¡»é
å synchronized 使ç¨ï¼wait æ¹æ³éæ¾éï¼notify æ¹æ³ä¸éæ¾éãwait æ¯æå¨ä¸ä¸ªå·²ç»è¿å
¥äºåæ¥éç线ç¨å
ï¼è®©èªå·±ææ¶è®©åºåæ¥éï¼ä»¥ä¾¿å
¶ä»æ£å¨çå¾
æ¤éç线ç¨å¯ä»¥å¾å°åæ¥éå¹¶è¿è¡ï¼åªæå
¶ä»çº¿ç¨è°ç¨äºnotify()ï¼notifyå¹¶ä¸éæ¾éï¼åªæ¯åè¯è°ç¨è¿wait()ç线ç¨å¯ä»¥å»åä¸è·å¾éçç«äºäºï¼ä½ä¸æ¯é©¬ä¸å¾å°éï¼å 为éè¿å¨å«äººæéï¼å«äººè¿æ²¡éæ¾ï¼è°ç¨ wait() çä¸ä¸ªæå¤ä¸ªçº¿ç¨å°±ä¼è§£é¤ wait ç¶æï¼éæ°åä¸ç«äºå¯¹è±¡éï¼ç¨åºå¦æå¯ä»¥å次å¾å°éï¼å°±å¯ä»¥ç»§ç»åä¸è¿è¡ã
2ãä½¿ç¨ volatile å ³é®åãåºäºvolatileå ³é®åå®ç°çº¿ç¨é´ç¸äºéä¿¡ï¼å ¶åºå±ä½¿ç¨äºå ±äº«å åãç®åæ¥è¯´ï¼å°±æ¯å¤ä¸ªçº¿ç¨åæ¶çå¬ä¸ä¸ªåéï¼å½è¿ä¸ªåéåçååçæ¶å ï¼çº¿ç¨è½å¤æç¥å¹¶æ§è¡ç¸åºçä¸å¡ã
3ã使ç¨JUCå·¥å
·ç±» CountDownLatchãjdk1.5 ä¹åå¨java.util.concurrentå
䏿ä¾äºå¾å¤å¹¶åç¼ç¨ç¸å
³çå·¥å
·ç±»ï¼ç®åäºå¹¶åç¼ç¨å¼åï¼CountDownLatch åºäº AQS æ¡æ¶ï¼ç¸å½äºä¹æ¯ç»´æ¤äºä¸ä¸ªçº¿ç¨é´å
±äº«åé stateã
4ãåºäº LockSupport å®ç°çº¿ç¨é´çé»å¡åå¤éãLockSupport æ¯ä¸ç§éå¸¸çµæ´»çå®ç°çº¿ç¨é´é»å¡åå¤éçå·¥å
·ï¼ä½¿ç¨å®ä¸ç¨å
³æ³¨æ¯çå¾
线ç¨å
è¿è¡è¿æ¯å¤é线ç¨å
è¿è¡ï¼ä½æ¯å¾ç¥é线ç¨çååã
ThreadLocal
ThreadLocalæ¯ä»ä¹
çº¿ç¨æ¬å°åéãå½ä½¿ç¨ThreadLocalç»´æ¤åéæ¶ï¼ThreadLocal为æ¯ä¸ªä½¿ç¨è¯¥åéççº¿ç¨æä¾ç¬ç«çåé坿¬ï¼æä»¥æ¯ä¸ä¸ªçº¿ç¨é½å¯ä»¥ç¬ç«å°æ¹åèªå·±ç坿¬ï¼èä¸ä¼å½±åå
¶å®çº¿ç¨ã
为ä»ä¹è¦ä½¿ç¨ThreadLocalï¼
å¹¶ååºæ¯ä¸ï¼ä¼åå¨å¤ä¸ªçº¿ç¨åæ¶ä¿®æ¹ä¸ä¸ªå ±äº«åéçåºæ¯ãè¿å°±å¯è½ä¼åºç°çº¿æ§å®å ¨é®é¢ã
为äºè§£å³çº¿æ§å®å
¨é®é¢ï¼å¯ä»¥ç¨å éçæ¹å¼ï¼æ¯å¦ä½¿ç¨synchronized æè
Lockã使¯å éçæ¹å¼ï¼å¯è½ä¼å¯¼è´ç³»ç»åæ
¢ã
è¿æå¦å¤ä¸ç§æ¹æ¡ï¼å°±æ¯ä½¿ç¨ç©ºé´æ¢æ¶é´çæ¹å¼ï¼å³ä½¿ç¨ThreadLocalã使ç¨ThreadLocal类访é®å
±äº«åéæ¶ï¼ä¼å¨æ¯ä¸ªçº¿ç¨çæ¬å°ï¼é½ä¿åä¸ä»½å
±äº«åéçæ·è´å¯æ¬ãå¤çº¿ç¨å¯¹å
±äº«åéä¿®æ¹æ¶ï¼å®é
䏿ä½çæ¯è¿ä¸ªåé坿¬ï¼ä»èä¿è¯çº¿æ§å®å
¨ã
ThreadåThreadLocalæä»ä¹èç³»å¢ï¼
ThreadåThreadLocalæ¯ç»å®çï¼ ThreadLocalä¾èµäºThread廿§è¡ï¼ Threadå°éè¦éç¦»çæ°æ®åæ¾å°ThreadLocal(åç¡®ç讲æ¯ThreadLocalMap)ä¸ï¼æ¥å®ç°å¤çº¿ç¨å¤çã
说说ThreadLocalçåçï¼
æ¯ä¸ªçº¿ç¨é½æä¸ä¸ªThreadLocalMapï¼ThreadLocalå
é¨ç±»ï¼ï¼Mapä¸å
ç´ çé®ä¸ºThreadLocalï¼èå¼å¯¹åºçº¿ç¨çåé坿¬ã

è°ç¨threadLocal.set()-->è°ç¨getMap(Thread)-->è¿åå½å线ç¨çThreadLocalMap<ThreadLocal, value>-->map.set(this, value)ï¼thisæ¯threadLocalæ¬èº«ãæºç å¦ä¸ï¼
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
è°ç¨get()-->è°ç¨getMap(Thread)-->è¿åå½å线ç¨çThreadLocalMap<ThreadLocal, value>-->map.getEntry(this)ï¼è¿åvalueãæºç å¦ä¸ï¼
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
threadLocalsçç±»åThreadLocalMapçé®ä¸ºThreadLocal对象ï¼å 为æ¯ä¸ªçº¿ç¨ä¸å¯æå¤ä¸ªthreadLocalåéï¼å¦longLocalåstringLocalã
public class ThreadLocalDemo {
ThreadLocal<Long> longLocal = new ThreadLocal<>();
public void set() {
longLocal.set(Thread.currentThread().getId());
}
public Long get() {
return longLocal.get();
}
public static void main(String[] args) throws InterruptedException {
ThreadLocalDemo threadLocalDemo = new ThreadLocalDemo();
threadLocalDemo.set();
System.out.println(threadLocalDemo.get());
Thread thread = new Thread(() -> {
threadLocalDemo.set();
System.out.println(threadLocalDemo.get());
}
);
thread.start();
thread.join();
System.out.println(threadLocalDemo.get());
}
}
ThreadLocal并䏿¯ç¨æ¥è§£å³å
±äº«èµæºçå¤çº¿ç¨è®¿é®é®é¢ï¼å 为æ¯ä¸ªçº¿ç¨ä¸çèµæºåªæ¯å¯æ¬ï¼ä¸ä¼å
±äº«ãå æ¤ThreadLocaléåä½ä¸ºçº¿ç¨ä¸ä¸æåéï¼ç®å线ç¨å
ä¼ åã
ThreadLocalå åæ³æ¼çåå ï¼
æ¯ä¸ªçº¿ç¨é½æâ¼ä¸ªThreadLocalMapçå
é¨å±æ§ï¼mapçkeyæ¯ThreaLocalï¼å®ä¹ä¸ºå¼±å¼ç¨ï¼valueæ¯å¼ºå¼ç¨ç±»åãåå¾åæ¶çæ¶åä¼â¾å¨åæ¶keyï¼èvalueçåæ¶åå³äºThread对象ççå½å¨æãä¸è¬ä¼éè¿çº¿ç¨æ± çæ¹å¼å¤ç¨çº¿ç¨èçèµæºï¼è¿ä¹å°±å¯¼è´äºçº¿ç¨å¯¹è±¡ççå½å¨ææ¯è¾é¿ï¼è¿æ ·ä¾¿ä¸ç´åå¨ä¸æ¡å¼ºå¼ç¨é¾çå
³ç³»ï¼Thread --> ThreadLocalMap-->Entry-->Valueï¼éçä»»å¡çæ§è¡ï¼valueå°±æå¯è½è¶æ¥è¶å¤ä¸æ æ³éæ¾ï¼æç»å¯¼è´å
åæ³æ¼ã
è§£å³â½
æ³ï¼æ¯æ¬¡ä½¿â½¤å®ThreadLocalå°±è°â½¤å®çremove()â½
æ³ï¼æå¨å°å¯¹åºçé®å¼å¯¹å é¤ï¼ä»â½½é¿å
å
åæ³æ¼ã
ThreadLocal使ç¨åºæ¯æåªäºï¼
åºæ¯1
ThreadLocal ç¨ä½ä¿åæ¯ä¸ªçº¿ç¨ç¬äº«ç对象ï¼ä¸ºæ¯ä¸ªçº¿ç¨é½å建ä¸ä¸ªå¯æ¬ï¼è¿æ ·æ¯ä¸ªçº¿ç¨é½å¯ä»¥ä¿®æ¹èªå·±ææ¥æç坿¬, èä¸ä¼å½±åå ¶ä»çº¿ç¨ç坿¬ï¼ç¡®ä¿äºçº¿ç¨å®å ¨ã
è¿ç§åºæ¯é常ç¨äºä¿å线ç¨ä¸å®å ¨çå·¥å ·ç±»ï¼å ¸åç使ç¨çç±»å°±æ¯ SimpleDateFormatã
åå¦éæ±ä¸º500个线ç¨é½è¦ç¨å° SimpleDateFormatï¼ä½¿ç¨çº¿ç¨æ± æ¥å®ç°çº¿ç¨çå¤ç¨ï¼å¦å伿¶èè¿å¤çå åçèµæºï¼å¦ææä»¬æ¯ä¸ªä»»å¡é½å建äºä¸ä¸ª simpleDateFormat 对象ï¼ä¹å°±æ¯è¯´ï¼500个任å¡å¯¹åº500个 simpleDateFormat 对象ã使¯è¿ä¹å¤å¯¹è±¡çåå»ºæ¯æå¼éçï¼èä¸è¿ä¹å¤å¯¹è±¡åæ¶åå¨å¨å åä¸ä¹æ¯ä¸ç§å åçæµªè´¹ãå¯ä»¥å°simpleDateFormat å¯¹è±¡ç»æåäºåºæ¥ï¼åæéæåéï¼ä½æ¯è¿æ ·ä¸æ¥å°±ä¼æçº¿ç¨ä¸å®å ¨çé®é¢ãæä»¬æ³è¦çæææ¯ï¼æ¢ä¸æµªè´¹è¿å¤çå åï¼åæ¶åæ³ä¿è¯çº¿ç¨å®å ¨ãæ¤æ¶ï¼å¯ä»¥ä½¿ç¨ ThreadLocalæ¥è¾¾å°è¿ä¸ªç®çï¼æ¯ä¸ªçº¿ç¨é½æ¥æä¸ä¸ªèªå·±ç simpleDateFormat 对象ã
åºæ¯2
ThreadLocal ç¨ä½æ¯ä¸ªçº¿ç¨å éè¦ç¬ç«ä¿åä¿¡æ¯ï¼ä»¥ä¾¿ä¾å ¶ä»æ¹æ³æ´æ¹ä¾¿å°è·å该信æ¯çåºæ¯ãæ¯ä¸ªçº¿ç¨è·åå°çä¿¡æ¯å¯è½é½æ¯ä¸ä¸æ ·çï¼å颿§è¡çæ¹æ³ä¿åäºä¿¡æ¯åï¼åç»æ¹æ³å¯ä»¥éè¿ ThreadLocal ç´æ¥è·åå°ï¼é¿å äºä¼ åï¼ç±»ä¼¼äºå ¨å±åéçæ¦å¿µã
æ¯å¦Java webåºç¨ä¸ï¼æ¯ä¸ªçº¿ç¨æèªå·±åç¬çSessionå®ä¾ï¼å°±å¯ä»¥ä½¿ç¨ThreadLocalæ¥å®ç°ã
ä»ä¹æ¯AQSï¼
AQSï¼AbstractQueuedSynchronizerï¼æ¯java.util.concurrentå ä¸çæ ¸å¿ç±»ï¼æä»¬ç»å¸¸ä½¿ç¨çReentrantLockãCountDownLatchï¼é½æ¯åºäºAQSæ½è±¡åæ¥å¼éåå®ç°çã
AQSä½ä¸ºä¸ä¸ªæ½è±¡ç±»ï¼é常æ¯éè¿ç»§æ¿æ¥ä½¿ç¨çã宿¬èº«æ¯æ²¡æåæ¥æ¥å£çï¼åªæ¯å®ä¹äºåæ¥ç¶æå忥è·åååæ¥éæ¾çæ¹æ³ã
JUCå ä¸é¢å¤§é¨ååæ¥ç±»ï¼é½æ¯åºäºAQSçåæ¥ç¶æçè·åä¸éæ¾æ¥å®ç°çï¼ç¶åAQSæ¯ä¸ªååé¾è¡¨ã
为ä»ä¹AQSæ¯ååé¾è¡¨è䏿¯ååçï¼
ååé¾è¡¨æä¸¤ä¸ªæéï¼ä¸ä¸ªæéæååç½®èç¹ï¼ä¸ä¸ªæéæååç»§èç¹ãæä»¥ï¼ååé¾è¡¨å¯ä»¥æ¯æå¸¸é O(1) æ¶é´å¤æåº¦çæ åµä¸æ¾å°å驱èç¹ãå æ¤ï¼ååé¾è¡¨å¨æå ¥åå 餿ä½çæ¶åï¼è¦æ¯ååé¾è¡¨ç®åã髿ã
ä»ååé¾è¡¨çç¹æ§æ¥çï¼AQS 使ç¨ååé¾è¡¨æ2个æ¹é¢çåå ï¼
- 没æç«äºå°éç线ç¨å å ¥å°é»å¡éåï¼å¹¶ä¸é»å¡çå¾ çåææ¯ï¼å½åçº¿ç¨æå¨èç¹çåç½®èç¹æ¯æ£å¸¸ç¶æï¼è¿æ ·è®¾è®¡æ¯ä¸ºäºé¿å é¾è¡¨ä¸åå¨å¼å¸¸çº¿ç¨å¯¼è´æ æ³å¤éåç»çº¿ç¨çé®é¢ãæä»¥ï¼çº¿ç¨é»å¡ä¹åéè¦å¤æåç½®èç¹çç¶æï¼å¦ææ²¡ææéæååç½®èç¹ï¼å°±éè¦ä» Head èç¹å¼å§éåï¼æ§è½é常ä½ã
- å¨ Lock æ¥å£é颿ä¸ä¸ªlockInterruptibly()æ¹æ³ï¼è¿ä¸ªæ¹æ³è¡¨ç¤ºå¤äºéé»å¡ç线ç¨å è®¸è¢«ä¸æãä¹å°±æ¯è¯´ï¼æ²¡æç«äºå°éç线ç¨å å ¥å°åæ¥éåçå¾ ä»¥åï¼æ¯å 许å¤é¨çº¿ç¨éè¿interrupt()æ¹æ³è§¦åå¤é并䏿çãè¿ä¸ªæ¶åï¼è¢«ä¸æç线ç¨çç¶æä¼ä¿®æ¹æ CANCELLEDãè被æ 记为 CANCELLED ç¶æç线ç¨ï¼æ¯ä¸éè¦å»ç«äºéçï¼ä½æ¯å®ä»ç¶åå¨äºååé¾è¡¨éé¢ãè¿å°±æå³çå¨åç»çéç«äºä¸ï¼éè¦æè¿ä¸ªèç¹ä»é¾è¡¨éé¢ç§»é¤ï¼å¦åä¼å¯¼è´éé»å¡ççº¿ç¨æ æ³è¢«æ£å¸¸å¤éãå¨è¿ç§æ åµä¸ï¼å¦ææ¯ååé¾è¡¨ï¼å°±éè¦ä» Head èç¹å¼å§å¾ä¸é个éåï¼æ¾å°å¹¶ç§»é¤å¼å¸¸ç¶æçèç¹ãåæ ·æç乿¯è¾ä½ï¼è¿ä¼å¯¼è´éå¤éçæä½åéåæä½ä¹é´çç«äºã
AQSåç
AQSï¼AbstractQueuedSynchronizerï¼æ½è±¡éå忥å¨ï¼å®ä¹äºä¸å¥å¤çº¿ç¨è®¿é®å
±äº«èµæºç忥卿¡æ¶ï¼è®¸å¤å¹¶åå·¥å
·çå®ç°é½ä¾èµäºå®ï¼å¦å¸¸ç¨çReentrantLock/Semaphore/CountDownLatchã
AQS使ç¨ä¸ä¸ªvolatileçintç±»åçæååéstateæ¥è¡¨ç¤ºåæ¥ç¶æï¼éè¿CASä¿®æ¹åæ¥ç¶æçå¼ãå½çº¿ç¨è°ç¨ lock æ¹æ³æ¶ ï¼å¦æ state=0ï¼è¯´ææ²¡æä»»ä½çº¿ç¨å æå
±äº«èµæºçéï¼å¯ä»¥è·å¾éå¹¶å° stateå 1ã妿 stateä¸ä¸º0ï¼å说ææçº¿ç¨ç®åæ£å¨ä½¿ç¨å
±äº«åéï¼å
¶ä»çº¿ç¨å¿
é¡»å å
¥åæ¥éåè¿è¡çå¾
ã
private volatile int state;//å
±äº«åéï¼ä½¿ç¨volatile修饰ä¿è¯çº¿ç¨å¯è§æ§
忥å¨ä¾èµå é¨ç忥éåï¼ä¸ä¸ªFIFOååéåï¼æ¥å®æåæ¥ç¶æç管çï¼å½å线ç¨è·ååæ¥ç¶æå¤±è´¥æ¶ï¼åæ¥å¨ä¼å°å½å线ç¨ä»¥åçå¾ ç¶æï¼ç¬å æå ±äº« ï¼æé æä¸ºä¸ä¸ªèç¹ï¼Nodeï¼å¹¶å°å ¶å å ¥åæ¥éåå¹¶è¿è¡èªæï¼å½åæ¥ç¶æéæ¾æ¶ï¼ä¼æé¦èç¹ä¸çåç»§èç¹å¯¹åºç线ç¨å¤éï¼ä½¿å ¶å次å°è¯è·ååæ¥ç¶æã

ReentrantLock æ¯å¦ä½å®ç°å¯éå ¥æ§ç?
ReentrantLockå
é¨èªå®ä¹äºåæ¥å¨syncï¼å¨å éçæ¶åéè¿CASç®æ³ï¼å°çº¿ç¨å¯¹è±¡æ¾å°ä¸ä¸ªååé¾è¡¨ä¸ï¼æ¯æ¬¡è·åéçæ¶åï¼æ£æ¥å½åç»´æ¤çé£ä¸ªçº¿ç¨IDåå½å请æ±ç线ç¨IDæ¯å¦ ä¸è´ï¼å¦æä¸è´ï¼åæ¥ç¶æå 1ï¼è¡¨ç¤ºé被å½å线ç¨è·åäºå¤æ¬¡ã
æºç å¦ä¸ï¼
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
éçåç±»
å ¬å¹³éä¸éå ¬å¹³é
æç
§çº¿ç¨è®¿é®é¡ºåºè·å对象éãsynchronizedæ¯éå
¬å¹³éï¼Locké»è®¤æ¯éå
¬å¹³éï¼å¯ä»¥è®¾ç½®ä¸ºå
¬å¹³éï¼å
¬å¹³éä¼å½±åæ§è½ã
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
å ±äº«å¼ä¸ç¬å å¼é
å ±äº«å¼ä¸ç¬å å¼çæä¸»è¦åºå«å¨äºï¼å䏿¶å»ç¬å å¼åªè½æä¸ä¸ªçº¿ç¨è·ååæ¥ç¶æï¼èå ±äº«å¼å¨å䏿¶å»å¯ä»¥æå¤ä¸ªçº¿ç¨è·ååæ¥ç¶æãä¾å¦è¯»æä½å¯ä»¥æå¤ä¸ªçº¿ç¨åæ¶è¿è¡ï¼èåæä½å䏿¶å»åªè½æä¸ä¸ªçº¿ç¨è¿è¡åæä½ï¼å ¶ä»æä½é½ä¼è¢«é»å¡ã
æ²è§éä¸ä¹è§é
æ²è§éï¼æ¯æ¬¡è®¿é®èµæºé½ä¼å éï¼æ§è¡å®åæ¥ä»£ç éæ¾éï¼synchronizedåReentrantLockå±äºæ²è§éã
ä¹è§éï¼ä¸ä¼éå®èµæºï¼ææç线ç¨é½è½è®¿é®å¹¶ä¿®æ¹åä¸ä¸ªèµæºï¼å¦ææ²¡æå²çªå°±ä¿®æ¹æåå¹¶éåºï¼å¦åå°±ä¼ç»§ç»å¾ªç¯å°è¯ãä¹è§éæå¸¸è§çå®ç°å°±æ¯CASã
éç¨åºæ¯ï¼
- æ²è§ééååæä½å¤çåºæ¯ã
- ä¹è§ééå读æä½å¤çåºæ¯ï¼ä¸å éå¯ä»¥æå读æä½çæ§è½ã
ä¹è§éæä»ä¹é®é¢?
ä¹è§éé¿å äºæ²è§éç¬å 对象çé®é¢ï¼æé«äºå¹¶åæ§è½ï¼ä½å®ä¹æç¼ºç¹:
- ä¹è§éåªè½ä¿è¯ä¸ä¸ªå ±äº«åéçååæä½ã
- é¿æ¶é´èªæå¯è½å¯¼è´å¼é大ãåå¦CASé¿æ¶é´ä¸æåèä¸ç´èªæï¼ä¼ç»CPU带æ¥å¾å¤§çå¼éã
- ABAé®é¢ãCASçåçæ¯éè¿æ¯å¯¹å åå¼ä¸é¢æå¼æ¯å¦ä¸æ ·è夿å å弿¯å¦è¢«æ¹è¿ï¼ä½æ¯ä¼æä»¥ä¸é®é¢ï¼åå¦å åå¼åæ¥æ¯Aï¼ åæ¥è¢«ä¸æ¡çº¿ç¨æ¹ä¸ºBï¼æååè¢«æ¹æäºAï¼åCAS认为æ¤å åå¼å¹¶æ²¡æåçæ¹åãå¯ä»¥å¼å ¥çæ¬å·è§£å³è¿ä¸ªé®é¢ï¼æ¯æ¬¡åéæ´æ°é½æçæ¬å·å ä¸ã
ä»ä¹æ¯CASï¼
CASå
¨ç§°Compare And Swapï¼æ¯è¾ä¸äº¤æ¢ï¼æ¯ä¹è§éç主è¦å®ç°æ¹å¼ãCASå¨ä¸ä½¿ç¨éçæ
åµä¸å®ç°å¤çº¿ç¨ä¹é´çåé忥ãReentrantLockå
é¨çAQSåååç±»å
é¨é½ä½¿ç¨äºCASã
CASç®æ³æ¶åå°ä¸ä¸ªæä½æ°ï¼
- éè¦è¯»åçå åå¼Vã
- è¿è¡æ¯è¾çå¼Aã
- è¦åå ¥çæ°å¼Bã
åªæå½Vçå¼çäºAæ¶ï¼æä¼ä½¿ç¨ååæ¹å¼ç¨æ°å¼Bæ¥æ´æ°Vçå¼ï¼å¦åä¼ç»§ç»éè¯ç´å°æåæ´æ°å¼ã
以AtomicInteger为ä¾ï¼AtomicIntegerçgetAndIncrement()æ¹æ³åºå±å°±æ¯CASå®ç°ï¼å
³é®ä»£ç æ¯ compareAndSwapInt(obj, offset, expect, update)ï¼å
¶å«ä¹å°±æ¯ï¼å¦æobjå
çvalueåexpectç¸çï¼å°±è¯ææ²¡æå
¶ä»çº¿ç¨æ¹åè¿è¿ä¸ªåéï¼é£ä¹å°±æ´æ°å®ä¸ºupdateï¼å¦æä¸ç¸çï¼é£å°±ä¼ç»§ç»éè¯ç´å°æåæ´æ°å¼ã
CASåå¨çé®é¢ï¼
CAS ä¸å¤§é®é¢ï¼
ABAé®é¢ãCASéè¦å¨æä½å¼çæ¶åæ£æ¥å å弿¯å¦åçååï¼æ²¡æåçååæä¼æ´æ°å åå¼ã使¯å¦æå åå¼åæ¥æ¯Aï¼åæ¥åæäºBï¼ç¶åååæäºAï¼é£ä¹CASè¿è¡æ£æ¥æ¶ä¼åç°å¼æ²¡æåçååï¼ä½æ¯å®é 䏿¯æååçãABAé®é¢çè§£å³æè·¯å°±æ¯å¨åéå颿·»å çæ¬å·ï¼æ¯æ¬¡åéæ´æ°çæ¶åé½æçæ¬å·å ä¸ï¼è¿æ ·ååè¿ç¨å°±ä»
Aï¼Bï¼Aåæäº1Aï¼2Bï¼3AãJDKä»1.5å¼å§æä¾äºAtomicStampedReferenceç±»æ¥è§£å³ABAé®é¢ï¼ååæ´æ°å¸¦æçæ¬å·çå¼ç¨ç±»åã
å¾ªç¯æ¶é´é¿å¼é大ãCASæä½å¦æé¿æ¶é´ä¸æåï¼ä¼å¯¼è´å ¶ä¸ç´èªæï¼ç»CPU带æ¥é常大çå¼éã
åªè½ä¿è¯ä¸ä¸ªå ±äº«åéçååæä½ã对ä¸ä¸ªå ±äº«åéæ§è¡æä½æ¶ï¼CASè½å¤ä¿è¯ååæä½ï¼ä½æ¯å¯¹å¤ä¸ªå ±äº«åéæä½æ¶ï¼CASæ¯æ æ³ä¿è¯æä½çååæ§çã
Javaä»1.5å¼å§JDKæä¾äºAtomicReferenceç±»æ¥ä¿è¯å¼ç¨å¯¹è±¡ä¹é´çååæ§ï¼å¯ä»¥æå¤ä¸ªåéæ¾å¨ä¸ä¸ªå¯¹è±¡éæ¥è¿è¡CASæä½ã
å¹¶åå·¥å ·
å¨JDKçå¹¶åå éæä¾äºå 个é常æç¨çå¹¶åå·¥å ·ç±»ãCountDownLatchãCyclicBarrieråSemaphoreå·¥å ·ç±»æä¾äºä¸ç§å¹¶åæµç¨æ§å¶çææ®µã
CountDownLatch
CountDownLatchç¨äºæä¸ªçº¿ç¨çå¾ å ¶ä»çº¿ç¨æ§è¡å®ä»»å¡åæ§è¡ï¼ä¸thread.join()åè½ç±»ä¼¼ã常è§çåºç¨åºæ¯æ¯å¼å¯å¤ä¸ªçº¿ç¨åæ¶æ§è¡æä¸ªä»»å¡ï¼çå°ææä»»å¡æ§è¡å®åæ§è¡ç¹å®æä½ï¼å¦æ±æ»ç»è®¡ç»æã
public class CountDownLatchDemo {
static final int N = 4;
static CountDownLatch latch = new CountDownLatch(N);
public static void main(String[] args) throws InterruptedException {
for(int i = 0; i < N; i++) {
new Thread(new Thread1()).start();
}
latch.await(1000, TimeUnit.MILLISECONDS); //è°ç¨await()æ¹æ³ç线ç¨ä¼è¢«æèµ·ï¼å®ä¼çå¾
ç´å°countå¼ä¸º0æç»§ç»æ§è¡;çå¾
timeoutæ¶é´åcountå¼è¿æ²¡å为0çè¯å°±ä¼ç»§ç»æ§è¡
System.out.println("task finished");
}
static class Thread1 implements Runnable {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "starts working");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
}
}
è¿è¡ç»æï¼
Thread-0starts working
Thread-1starts working
Thread-2starts working
Thread-3starts working
task finished
CyclicBarrier
CyclicBarrier(忥å±é)ï¼ç¨äºä¸ç»çº¿ç¨äºç¸çå¾ å°æä¸ªç¶æï¼ç¶åè¿ç»çº¿ç¨ååæ¶æ§è¡ã
public CyclicBarrier(int parties, Runnable barrierAction) {
}
public CyclicBarrier(int parties) {
}
åæ°partiesæè®©å¤å°ä¸ªçº¿ç¨æè ä»»å¡çå¾ è³æä¸ªç¶æï¼åæ°barrierAction为å½è¿äºçº¿ç¨é½è¾¾å°æä¸ªç¶ææ¶ä¼æ§è¡çå 容ã
public class CyclicBarrierTest {
// 请æ±çæ°é
private static final int threadCount = 10;
// éè¦åæ¥ççº¿ç¨æ°é
private static final CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
public static void main(String[] args) throws InterruptedException {
// åå»ºçº¿ç¨æ±
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for (int i = 0; i < threadCount; i++) {
final int threadNum = i;
Thread.sleep(1000);
threadPool.execute(() -> {
try {
test(threadNum);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
threadPool.shutdown();
}
public static void test(int threadnum) throws InterruptedException, BrokenBarrierException {
System.out.println("threadnum:" + threadnum + "is ready");
try {
/**çå¾
60ç§ï¼ä¿è¯å线ç¨å®å
¨æ§è¡ç»æ*/
cyclicBarrier.await(60, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("-----CyclicBarrierException------");
}
System.out.println("threadnum:" + threadnum + "is finish");
}
}
è¿è¡ç»æå¦ä¸ï¼å¯ä»¥çåºCyclicBarrieræ¯å¯ä»¥éç¨çï¼
threadnum:0is ready
threadnum:1is ready
threadnum:2is ready
threadnum:3is ready
threadnum:4is ready
threadnum:4is finish
threadnum:3is finish
threadnum:2is finish
threadnum:1is finish
threadnum:0is finish
threadnum:5is ready
threadnum:6is ready
...
å½å个线ç¨é½å°è¾¾barrierç¶æåï¼ä¼ä»å个线ç¨ä¸éæ©ä¸ä¸ªçº¿ç¨å»æ§è¡Runnableã
CyclicBarrieråCountDownLatchåºå«
CyclicBarrier å CountDownLatch é½è½å¤å®ç°çº¿ç¨ä¹é´ççå¾ ã
CountDownLatchç¨äºæä¸ªçº¿ç¨çå¾ å ¶ä»çº¿ç¨æ§è¡å®ä»»å¡åæ§è¡ãCyclicBarrierç¨äºä¸ç»çº¿ç¨äºç¸çå¾ å°æä¸ªç¶æï¼ç¶åè¿ç»çº¿ç¨ååæ¶æ§è¡ã CountDownLatchç计æ°å¨åªè½ä½¿ç¨ä¸æ¬¡ï¼èCyclicBarrierç计æ°å¨å¯ä»¥ä½¿ç¨reset()æ¹æ³éç½®ï¼å¯ç¨äºå¤çæ´ä¸ºå¤æçä¸å¡åºæ¯ã
Semaphore
Semaphore类似äºéï¼å®ç¨äºæ§å¶åæ¶è®¿é®ç¹å®èµæºççº¿ç¨æ°éï¼æ§å¶å¹¶åçº¿ç¨æ°ã
public class SemaphoreDemo {
public static void main(String[] args) {
final int N = 7;
Semaphore s = new Semaphore(3);
for(int i = 0; i < N; i++) {
new Worker(s, i).start();
}
}
static class Worker extends Thread {
private Semaphore s;
private int num;
public Worker(Semaphore s, int num) {
this.s = s;
this.num = num;
}
@Override
public void run() {
try {
s.acquire();
System.out.println("worker" + num + " using the machine");
Thread.sleep(1000);
System.out.println("worker" + num + " finished the task");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
è¿è¡ç»æå¦ä¸ï¼å¯ä»¥çåºå¹¶éæç §çº¿ç¨è®¿é®é¡ºåºè·åèµæºçéï¼å³
worker0 using the machine
worker1 using the machine
worker2 using the machine
worker2 finished the task
worker0 finished the task
worker3 using the machine
worker4 using the machine
worker1 finished the task
worker6 using the machine
worker4 finished the task
worker3 finished the task
worker6 finished the task
worker5 using the machine
worker5 finished the task
ååç±»
åºæ¬ç±»åååç±»
使ç¨ååçæ¹å¼æ´æ°åºæ¬ç±»å
- AtomicIntegerï¼æ´åååç±»
- AtomicLongï¼é¿æ´åååç±»
- AtomicBoolean ï¼å¸å°åååç±»
AtomicInteger 类常ç¨çæ¹æ³ï¼
public final int get() //è·åå½åçå¼
public final int getAndSet(int newValue)//è·åå½åçå¼ï¼å¹¶è®¾ç½®æ°çå¼
public final int getAndIncrement()//è·åå½åçå¼ï¼å¹¶èªå¢
public final int getAndDecrement() //è·åå½åçå¼ï¼å¹¶èªå
public final int getAndAdd(int delta) //è·åå½åçå¼ï¼å¹¶å ä¸é¢æçå¼
boolean compareAndSet(int expect, int update) //妿è¾å
¥çæ°å¼çäºé¢æå¼ï¼å以ååæ¹å¼å°è¯¥å¼è®¾ç½®ä¸ºè¾å
¥å¼ï¼updateï¼
public final void lazySet(int newValue)//æç»è®¾ç½®ä¸ºnewValue,ä½¿ç¨ lazySet 设置ä¹åå¯è½å¯¼è´å
¶ä»çº¿ç¨å¨ä¹åçä¸å°æ®µæ¶é´å
è¿æ¯å¯ä»¥è¯»å°æ§çå¼ã
AtomicInteger 类主è¦å©ç¨ CAS (compare and swap) ä¿è¯ååæä½ï¼ä»èé¿å å éçé«å¼éã
æ°ç»ç±»åååç±»
使ç¨ååçæ¹å¼æ´æ°æ°ç»éçæä¸ªå ç´
- AtomicIntegerArrayï¼æ´å½¢æ°ç»ååç±»
- AtomicLongArrayï¼é¿æ´å½¢æ°ç»ååç±»
- AtomicReferenceArray ï¼å¼ç¨ç±»åæ°ç»ååç±»
AtomicIntegerArray ç±»å¸¸ç¨æ¹æ³ï¼
public final int get(int i) //è·å index=i ä½ç½®å
ç´ çå¼
public final int getAndSet(int i, int newValue)//è¿å index=i ä½ç½®çå½åçå¼ï¼å¹¶å°å
¶è®¾ç½®ä¸ºæ°å¼ï¼newValue
public final int getAndIncrement(int i)//è·å index=i ä½ç½®å
ç´ çå¼ï¼å¹¶è®©è¯¥ä½ç½®çå
ç´ èªå¢
public final int getAndDecrement(int i) //è·å index=i ä½ç½®å
ç´ çå¼ï¼å¹¶è®©è¯¥ä½ç½®çå
ç´ èªå
public final int getAndAdd(int i, int delta) //è·å index=i ä½ç½®å
ç´ çå¼ï¼å¹¶å ä¸é¢æçå¼
boolean compareAndSet(int i, int expect, int update) //妿è¾å
¥çæ°å¼çäºé¢æå¼ï¼å以ååæ¹å¼å° index=i ä½ç½®çå
ç´ å¼è®¾ç½®ä¸ºè¾å
¥å¼ï¼updateï¼
public final void lazySet(int i, int newValue)//æç» å°index=i ä½ç½®çå
ç´ è®¾ç½®ä¸ºnewValue,ä½¿ç¨ lazySet 设置ä¹åå¯è½å¯¼è´å
¶ä»çº¿ç¨å¨ä¹åçä¸å°æ®µæ¶é´å
è¿æ¯å¯ä»¥è¯»å°æ§çå¼ã
å¼ç¨ç±»åååç±»
- AtomicReferenceï¼å¼ç¨ç±»åååç±»
- AtomicStampedReferenceï¼å¸¦æçæ¬å·çå¼ç¨ç±»åååç±»ãè¯¥ç±»å°æ´æ°å¼ä¸å¼ç¨å ³èèµ·æ¥ï¼å¯ç¨äºè§£å³ååçæ´æ°æ°æ®åæ°æ®ççæ¬å·ï¼å¯ä»¥è§£å³ä½¿ç¨ CAS è¿è¡ååæ´æ°æ¶å¯è½åºç°ç ABA é®é¢ã
- AtomicMarkableReference ï¼ååæ´æ°å¸¦ææ è®°çå¼ç¨ç±»åãè¯¥ç±»å° boolean æ è®°ä¸å¼ç¨å ³èèµ·æ¥
ä»ä¹æ¯Daemon线ç¨ï¼
åå°(daemon)线ç¨ï¼æ¯æå¨ç¨åºè¿è¡çæ¶åå¨åå°æä¾ä¸ç§éç¨æå¡ç线ç¨ï¼å¹¶ä¸è¿ä¸ªçº¿ç¨å¹¶ä¸å±äºç¨åºä¸ä¸å¯æç¼ºçé¨åãå æ¤ï¼å½ææçéåå°çº¿ç¨ç»ææ¶ï¼ç¨åºä¹å°±ç»æ¢äºï¼åæ¶ä¼ææ»è¿ç¨ä¸çææåå°çº¿ç¨ãåè¿æ¥è¯´ï¼åªè¦æä»»ä½éåå°çº¿ç¨è¿å¨è¿è¡ï¼ç¨åºå°±ä¸ä¼ç»æ¢ãå¿ é¡»å¨çº¿ç¨å¯å¨ä¹åè°ç¨setDaemon()æ¹æ³ï¼æè½æå®è®¾ç½®ä¸ºåå°çº¿ç¨ã
注æï¼åå°è¿ç¨å¨ä¸æ§è¡finallyåå¥çæ åµä¸å°±ä¼ç»æ¢å ¶run()æ¹æ³ã
æ¯å¦ï¼JVMçåå¾åæ¶çº¿ç¨å°±æ¯Daemon线ç¨ï¼Finalizer乿¯å®æ¤çº¿ç¨ã
SynchronizedMapåConcurrentHashMapæä»ä¹åºå«ï¼
SynchronizedMap䏿¬¡é使´å¼ 表æ¥ä¿è¯çº¿ç¨å®å ¨ï¼æä»¥æ¯æ¬¡åªè½æä¸ä¸ªçº¿ç¨æ¥è®¿é®mapã
JDK1.8 ConcurrentHashMapéç¨CASåsynchronizedæ¥ä¿è¯å¹¶åå®å ¨ãæ°æ®ç»æéç¨æ°ç»+é¾è¡¨/红é»äºåæ ãsynchronizedåªéå®å½åé¾è¡¨æçº¢é»äºåæ çé¦èç¹ï¼æ¯æå¹¶å访é®ãä¿®æ¹ã å¦å¤ConcurrentHashMap使ç¨äºä¸ç§ä¸åçè¿ä»£æ¹å¼ãå½iterator被å建åéåååçæ¹åå°±ä¸åæ¯æåºConcurrentModificationExceptionï¼åè代ä¹çæ¯å¨æ¹åæ¶newæ°çæ°æ®ä»èä¸å½±ååæçæ°æ® ï¼iterator宿ååå°å¤´æéæ¿æ¢ä¸ºæ°çæ°æ® ï¼è¿æ ·iterator线ç¨å¯ä»¥ä½¿ç¨åæ¥èçæ°æ®ï¼èå线ç¨ä¹å¯ä»¥å¹¶åç宿æ¹åã
ä»ä¹æ¯Futureï¼
å¨å¹¶åç¼ç¨ä¸ï¼ä¸ç®¡æ¯ç»§æ¿threadç±»è¿æ¯å®ç°runnableæ¥å£ï¼é½æ æ³ä¿è¯è·åå°ä¹åçæ§è¡ç»æãéè¿å®ç°Callbackæ¥å£ï¼å¹¶ç¨Futureå¯ä»¥æ¥æ¥æ¶å¤çº¿ç¨çæ§è¡ç»æã
Future表示ä¸ä¸ªå¯è½è¿æ²¡æå®æç弿¥ä»»å¡çç»æï¼é对è¿ä¸ªç»æå¯ä»¥æ·»å Callback以便å¨ä»»å¡æ§è¡æåæå¤±è´¥åä½åºç¸åºçæä½ã
举个ä¾åï¼æ¯å¦å»åæ©ç¹æ¶ï¼ç¹äºå åååèï¼å åéè¦ç3åéï¼åèåªé1åéï¼å¦ææ¯ä¸²è¡çä¸ä¸ªæ§è¡ï¼å¨å䏿©ç¹çæ¶åéè¦çå¾ 4åéï¼ä½æ¯å ä¸ºä½ å¨çå åçæ¶åï¼å¯ä»¥åæ¶åå¤åèï¼æä»¥å¨åå¤åèçè¿ç¨ä¸ï¼å¯ä»¥åæ¶åå¤å åï¼è¿æ ·åªéè¦çå¾ 3åéãFutureå°±æ¯åé¢è¿ç§æ§è¡æ¨¡å¼ã
Futureæ¥å£ä¸»è¦å æ¬5ä¸ªæ¹æ³ï¼
- get()æ¹æ³å¯ä»¥å½ä»»å¡ç»æåè¿åä¸ä¸ªç»æï¼å¦æè°ç¨æ¶ï¼å·¥ä½è¿æ²¡æç»æï¼åä¼é»å¡çº¿ç¨ï¼ç´å°ä»»å¡æ§è¡å®æ¯
- get(long timeout,TimeUnit unit)åå¤çå¾ timeoutçæ¶é´å°±ä¼è¿åç»æ
- cancel(boolean mayInterruptIfRunning)æ¹æ³å¯ä»¥ç¨æ¥åæ¢ä¸ä¸ªä»»å¡ï¼å¦æä»»å¡å¯ä»¥åæ¢ï¼éè¿mayInterruptIfRunningæ¥è¿è¡å¤æï¼ï¼åå¯ä»¥è¿åtrueï¼å¦æä»»å¡å·²ç»å®ææè å·²ç»åæ¢ï¼æè è¿ä¸ªä»»å¡æ æ³åæ¢ï¼åä¼è¿åfalseã
- isDone()æ¹æ³å¤æå½åæ¹æ³æ¯å¦å®æ
- isCancel()æ¹æ³å¤æå½åæ¹æ³æ¯å¦åæ¶
selectãpollãepollä¹é´çåºå«
selectï¼pollï¼epoll齿¯IOå¤è·¯å¤ç¨çæºå¶ãI/Oå¤è·¯å¤ç¨å°±éè¿ä¸ç§æºå¶ï¼å¯ä»¥çè§å¤ä¸ªæè¿°ç¬¦ï¼ä¸æ¦æä¸ªæè¿°ç¬¦å°±ç»ªï¼ä¸è¬æ¯è¯»å°±ç»ªæè å就绪ï¼ï¼è½å¤éç¥ç¨åºè¿è¡ç¸åºç读åæä½ãä½selectï¼pollï¼epollæ¬è´¨ä¸é½æ¯åæ¥I/Oï¼å 为ä»ä»¬é½éè¦å¨è¯»åäºä»¶å°±ç»ªåèªå·±è´è´£è¿è¡è¯»åï¼ä¹å°±æ¯è¯´è¿ä¸ªè¯»åè¿ç¨æ¯é»å¡çï¼è弿¥I/Oåæ éèªå·±è´è´£è¿è¡è¯»åï¼å¼æ¥I/Oçå®ç°ä¼è´è´£ææ°æ®ä»å æ ¸æ·è´å°ç¨æ·ç©ºé´ã
selectçæ¶é´å¤æåº¦O(n)ãå®ä» ä» ç¥éæI/Oäºä»¶åçäºï¼å´å¹¶ä¸ç¥éæ¯åªé£å 个æµï¼åªè½æ å·®å«è½®è¯¢æææµï¼æ¾åºè½è¯»åºæ°æ®ï¼æè åå ¥æ°æ®çæµï¼å¯¹ä»ä»¬è¿è¡æä½ãæä»¥selectå ·æO(n)çæ¶é´å¤æåº¦ï¼åæ¶å¤ççæµè¶å¤ï¼è½®è¯¢æ¶é´å°±è¶é¿ã
pollçæ¶é´å¤æåº¦O(n)ãpollæ¬è´¨ä¸åselect没æåºå«ï¼å®å°ç¨æ·ä¼ å ¥çæ°ç»æ·è´å°å æ ¸ç©ºé´ï¼ç¶åæ¥è¯¢æ¯ä¸ªfd对åºç设å¤ç¶æï¼ 使¯å®æ²¡ææå¤§è¿æ¥æ°çéå¶ï¼åå æ¯å®æ¯åºäºé¾è¡¨æ¥åå¨ç.
epollçæ¶é´å¤æåº¦O(1)ãepollå¯ä»¥ç解为event pollï¼ä¸åäºå¿è½®è¯¢åæ å·®å«è½®è¯¢ï¼epoll伿åªä¸ªæµåçäºææ ·çI/Oäºä»¶éç¥æä»¬ãæä»¥æä»¬è¯´epollå®é 䏿¯äºä»¶é©±å¨çã
åè龿¥ï¼https://blog.csdn.net/u014209205/article/details/80598209
ReadWriteLock å StampedLock çåºå«
å¨å¤çº¿ç¨ç¼ç¨ä¸ï¼å¯¹äºå ±äº«èµæºçè®¿é®æ§å¶æ¯ä¸ä¸ªé常éè¦çé®é¢ãå¨å¹¶åç¯å¢ä¸ï¼å¤ä¸ªçº¿ç¨åæ¶è®¿é®å ±äº«èµæºå¯è½ä¼å¯¼è´æ°æ®ä¸ä¸è´çé®é¢ï¼å æ¤éè¦ä¸ç§æºå¶æ¥ä¿è¯æ°æ®çä¸è´æ§åå¹¶åæ§ã
Javaæä¾äºå¤ç§æºå¶æ¥å®ç°å¹¶åæ§å¶ï¼å ¶ä¸ ReadWriteLock å StampedLock æ¯ä¸¤ä¸ªå¸¸ç¨çéç±»ãæ¬æå°åå«ä»ç»è¿ä¸¤ä¸ªç±»çç¹æ§ã使ç¨åºæ¯ä»¥å示ä¾ä»£ç ã
ReadWriteLock
ReadWriteLock æ¯Javaæä¾çä¸ä¸ªæ¥å£ï¼å
¨ç±»åï¼java.util.concurrent.locks.ReentrantLockãå®å
许å¤ä¸ªçº¿ç¨åæ¶è¯»åå
±äº«èµæºï¼ä½åªå
许ä¸ä¸ªçº¿ç¨åå
¥å
±äº«èµæºãè¿ç§æºå¶å¯ä»¥æé«è¯»åæä½çå¹¶åæ§ï¼ä½åå
¥æä½éè¦ç¬å èµæºã
ç¹æ§
- å¤ä¸ªçº¿ç¨å¯ä»¥åæ¶è·å读éï¼ä½åªæä¸ä¸ªçº¿ç¨å¯ä»¥è·ååéã
- å½ä¸ä¸ªçº¿ç¨ææåéæ¶ï¼å ¶ä»çº¿ç¨æ æ³è·å读éååéï¼è¯»åäºæ¥ã
- å½ä¸ä¸ªçº¿ç¨ææè¯»éæ¶ï¼å ¶ä»çº¿ç¨å¯ä»¥åæ¶è·å读éï¼è¯»è¯»å ±äº«ã
使ç¨åºæ¯
ReadWriteLock éç¨äºè¯»å¤åå°çåºæ¯ï¼ä¾å¦ç¼åç³»ç»ãæ°æ®åºè¿æ¥æ± çãå¨è¿äºåºæ¯ä¸ï¼è¯»åæä½å æ®å¤§é¨åæ¶é´ï¼èåå ¥æä½è¾å°ã
示ä¾ä»£ç
ä¸é¢æ¯ä¸ä¸ªä½¿ç¨ ReadWriteLock ç示ä¾ï¼å®ç°äºä¸ä¸ªç®åçç¼åç³»ç»ï¼
public class Cache {
private Map<String, Object> data = new HashMap<>();
private ReadWriteLock lock = new ReentrantReadWriteLock();
public Object get(String key) {
lock.readLock().lock();
try {
return data.get(key);
} finally {
lock.readLock().unlock();
}
}
public void put(String key, Object value) {
lock.writeLock().lock();
try {
data.put(key, value);
} finally {
lock.writeLock().unlock();
}
}
}
å¨ä¸è¿°ç¤ºä¾ä¸ï¼Cache ç±»ä½¿ç¨ ReadWriteLock æ¥å®ç°å¯¹ data çå¹¶åè®¿é®æ§å¶ãget æ¹æ³è·å读éå¹¶è¯»åæ°æ®ï¼put æ¹æ³è·ååéå¹¶åå ¥æ°æ®ã
StampedLock
StampedLock æ¯Java 8 ä¸å¼å
¥çä¸ç§æ°çéæºå¶ï¼å
¨ç±»åï¼java.util.concurrent.locks.StampedLockï¼å®æä¾äºä¸ç§ä¹è§è¯»çæºå¶ï¼å¯ä»¥è¿ä¸æ¥æå读åæä½çå¹¶åæ§è½ã
ç¹æ§
- ä¸ ReadWriteLock 类似ï¼StampedLock 乿¯æå¤ä¸ªçº¿ç¨åæ¶è·å读éï¼ä½åªå 许ä¸ä¸ªçº¿ç¨è·ååéã
- ä¸ ReadWriteLock ä¸åçæ¯ï¼StampedLock è¿æä¾äºä¸ä¸ªä¹è§è¯»éï¼Optimistic Read Lockï¼ï¼å³ä¸é»å¡å ¶ä»çº¿ç¨çåæä½ï¼ä½å¨è¯»å宿åéè¦éªè¯æ°æ®çä¸è´æ§ã
使ç¨åºæ¯
StampedLock éç¨äºè¯»è¿è¿å¤§äºåçåºæ¯ï¼å¹¶ä¸å¯¹æ°æ®çä¸è´æ§è¦æ±ä¸é«ï¼ä¾å¦ç»è®¡æ°æ®ãçæ§ç³»ç»çã
示ä¾ä»£ç
ä¸é¢æ¯ä¸ä¸ªä½¿ç¨ StampedLock ç示ä¾ï¼å®ç°äºä¸ä¸ªè®¡æ°å¨ï¼
public class Counter {
private int count = 0;
private StampedLock lock = new StampedLock();
public int getCount() {
long stamp = lock.tryOptimisticRead();
int value = count;
if (!lock.validate(stamp)) {
stamp = lock.readLock();
try {
value = count;
} finally {
lock.unlockRead(stamp);
}
}
return value;
}
public void increment() {
long stamp = lock.writeLock();
try {
count++;
} finally {
lock.unlockWrite(stamp);
}
}
}
å¨ä¸è¿°ç¤ºä¾ä¸ï¼Counter ç±»ä½¿ç¨ StampedLock æ¥å®ç°å¯¹è®¡æ°å¨çå¹¶åè®¿é®æ§å¶ãgetCount æ¹æ³é¦å å°è¯è·åä¹è§è¯»éï¼å¹¶è¯»å计æ°å¨çå¼ï¼ç¶åéè¿ validate æ¹æ³éªè¯æ°æ®çä¸è´æ§ã妿éªè¯å¤±è´¥ï¼åè·åæ²è§è¯»éï¼å¹¶éæ°è¯»å计æ°å¨çå¼ãincrement æ¹æ³è·ååéï¼å¹¶å¯¹è®¡æ°å¨è¿è¡é墿ä½ã
æ»ç»
ReadWriteLock å StampedLock 齿¯Javaä¸ç¨äºå¹¶åæ§å¶çéè¦æºå¶ã
- ReadWriteLock éç¨äºè¯»å¤åå°çåºæ¯;
- StampedLock åéç¨äºè¯»è¿è¿å¤§äºåçåºæ¯ï¼å¹¶ä¸å¯¹æ°æ®çä¸è´æ§è¦æ±ä¸é«;
å¨å®é åºç¨ä¸ï¼æä»¬éè¦æ ¹æ®å ·ä½åºæ¯æ¥éæ©åéçéæºå¶ãéè¿åç使ç¨è¿äºéæºå¶ï¼æä»¬å¯ä»¥æé«å¹¶åç¨åºçæ§è½åå¯é æ§ã
