1.JAVA如何获取jvm中的线程线程所有线程?
2.Java的并行世界-Netty中线程模型源码讲解-续集Handler、Channel
3.Java并发编程笔记之LinkedBlockingQueue源码探究
4.JAVA 线ç¨
5.Java多线程——singleThreadExecutor
JAVA如何获取jvm中的源码源码所有线程?
在Java中,你可以通过Java的线程线程java.lang.management包获取JVM中的所有线程。这个包提供了一些用于管理和监视Java虚拟机的源码源码工具。具体来说,线程线程你可以使用ThreadMXBean接口来获取线程信息。源码源码php题库源码
以下是线程线程一段示例代码,演示如何获取和打印JVM中的源码源码所有线程:
java复制代码
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class Main {
public static void main(String[] args) {
// 获取ThreadMXBean
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 不需要获取同步的monitor和synchronizer信息,仅获取线程和线程堆栈信息
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false,线程线程 false);
// 遍历线程信息,仅打印线程ID和线程名称信息
for (ThreadInfo threadInfo : threadInfos) {
System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName());
}
}
}
这段代码首先通过ManagementFactory.getThreadMXBean()获取ThreadMXBean实例,源码源码然后调用dumpAllThreads()方法获取所有线程的线程线程ThreadInfo,最后遍历并打印所有线程的源码源码ID和名称。
需要注意的线程线程是,dumpAllThreads()方法会返回一个ThreadInfo数组,源码源码每个ThreadInfo代表一个线程,线程线程网页软件库源码包含了关于该线程的大量信息,包括线程ID、线程名称、线程状态、线程堆栈信息等。在上面的示例代码中,我们只打印了线程ID和线程名称,但你可以根据需要打印其他信息。
Java的并行世界-Netty中线程模型源码讲解-续集Handler、Channel
Netty 的核心组件 ChannelHandler 在网络应用中扮演着关键角色,它处理各种事件和数据,实现业务逻辑。ChannelHandler 子类众多,根据功能可分为特殊Handler(如Context对象)、显示市盈率公式源码出入站Handler,以及用于协议解析和编码的Decoder和Encoder。例如,ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter 分别用于处理入站和出站事件,ByteToMessageDecoder 和 MessageToByteEncoder 则负责数据的解码和编码。
特殊Handler如ChannelHandlerContext 提供了处理器与Channel交互的上下文,而ChannelDuplexHandler 则用于双向通信,如聊天服务器。SimpleChannelInboundHandler 是简化版的入站处理器,自动管理消息引用,避免内存泄漏。而出站处理器如SimpleChannelOutboundHandler 则在消息处理后自动释放引用,简化编码流程。
Channel 是传奇源码怎么使用数据传输的抽象,NioServerSocketChannel 和 EpollServerSocketChannel 分别对应基于NIO和Epoll的服务器端套接字。ChannelInitializer 是初始化新Channel的关键,它配置处理器形成处理链,用于处理连接操作和事件,从而实现自定义业务逻辑。
通过理解这些概念和类的作用,可以构建和配置Netty应用,以满足不同的网络通信需求。想要深入学习,可以研究Netty 4.1源码中如EventLoopGroup、ChannelPipeline、CustomChannelInitializer等核心类。后续会分享详细的中文注释版本,持续关注以获取更多资源和知识。美刻日记源码
Java并发编程笔记之LinkedBlockingQueue源码探究
LinkedBlockingQueue 是基于单向链表实现的一种阻塞队列,其内部包含两个节点用于存放队列的首尾,并维护了一个表示元素个数的原子变量 count。同时,它利用了两个 ReentrantLock 实例(takeLock 和 putLock)来保证元素的原子性入队与出队操作。此外,notEmpty 和 notFull 两个信号量与条件队列用于实现阻塞操作,使得生产者和消费者模型得以实现。
LinkedBlockingQueue 的实现主要依赖于其内部锁机制和信号量管理。构造函数默认容量为最大整数值,用户可自定义容量大小。offer 方法用于尝试将元素添加至队列尾部,若队列未满则成功,返回 true,反之返回 false。若元素为 null,则抛出 NullPointerException。put 方法尝试将元素添加至队列尾部,并阻塞当前线程直至队列有空位,若被中断则抛出 InterruptedException。通过使用 putLock 锁,确保了元素的原子性添加以及元素计数的原子性更新。
在实现细节上,offer 方法通过在获取 putLock 的同时检查队列是否已满,避免了不必要的元素添加。若队列未满,则执行入队操作并更新计数器,同时考虑唤醒等待队列未满的线程。此过程中,通过 notFull 信号量与条件队列协调线程间等待与唤醒。
put 方法则在获取 putLock 后立即检查队列是否满,若满则阻塞当前线程至 notFull 信号量被唤醒。在入队后,更新计数器,并考虑唤醒等待队列未满的线程,同样通过 notFull 信号量实现。
poll 方法用于从队列头部获取并移除元素,若队列为空则返回 null。此方法通过获取 takeLock 锁,保证了在检查队列是否为空和执行出队操作之间的原子性。在出队后,计数器递减,并考虑激活因调用 poll 或 take 方法而被阻塞的线程。
peek 方法类似,但不移除队列头部元素,返回 null 若队列为空。此方法也通过获取 takeLock 锁来保证操作的原子性。
take 方法用于阻塞获取队列头部元素并移除,若队列为空则阻塞当前线程直至队列不为空。此方法与 put 方法类似,通过 notEmpty 信号量与条件队列协调线程间的等待与唤醒。
remove 方法用于移除并返回指定元素,若存在则返回 true,否则返回 false。此方法通过双重加锁机制(fullyLock 和 fullyUnlock)来确保元素移除操作的原子性。
size 方法用于返回当前队列中的元素数量,通过 count.get() 直接获取,确保了操作的准确性。
综上所述,LinkedBlockingQueue 通过其独特的锁机制和信号量管理,实现了高效、线程安全的阻塞队列操作,适用于生产者-消费者模型等场景。
JAVA 线ç¨
è¿æ¯javaeyeä¸é常ç»å ¸çå ³äºçº¿ç¨çå¸åï¼åçé常éä¿ææçï¼éåä»»ä½è¯»è®¡ç®æºçåå¦.
线ç¨åæ¥
æ们å¯ä»¥å¨è®¡ç®æºä¸è¿è¡åç§è®¡ç®æºè½¯ä»¶ç¨åºãæ¯ä¸ä¸ªè¿è¡çç¨åºå¯è½å æ¬å¤ä¸ªç¬ç«è¿è¡ç线ç¨ï¼Threadï¼ã
线ç¨ï¼Threadï¼æ¯ä¸ä»½ç¬ç«è¿è¡çç¨åºï¼æèªå·±ä¸ç¨çè¿è¡æ ã线ç¨æå¯è½åå ¶ä»çº¿ç¨å ±äº«ä¸äºèµæºï¼æ¯å¦ï¼å åï¼æ件ï¼æ°æ®åºçã
å½å¤ä¸ªçº¿ç¨åæ¶è¯»ååä¸ä»½å ±äº«èµæºçæ¶åï¼å¯è½ä¼å¼èµ·å²çªãè¿æ¶åï¼æ们éè¦å¼å ¥çº¿ç¨âåæ¥âæºå¶ï¼å³åä½çº¿ç¨ä¹é´è¦æ个å æ¥åå°ï¼ä¸è½ä¸çªèæ¤ä¸å»æ¢ä½ä¸å¢ã
åæ¥è¿ä¸ªè¯æ¯ä»è±æsynchronizeï¼ä½¿åæ¶åçï¼ç¿»è¯è¿æ¥çãæä¹ä¸æç½ä¸ºä»ä¹è¦ç¨è¿ä¸ªå¾å®¹æå¼èµ·è¯¯è§£çè¯ãæ¢ç¶å¤§å®¶é½è¿ä¹ç¨ï¼å±ä»¬ä¹å°±åªå¥½è¿ä¹å°å°±ã
线ç¨åæ¥ççå®ææååé¢æææ°å¥½ç¸åã线ç¨åæ¥ççå®ææï¼å ¶å®æ¯âæéâï¼å 个线ç¨ä¹é´è¦æéï¼ä¸ä¸ªä¸ä¸ªå¯¹å ±äº«èµæºè¿è¡æä½ï¼èä¸æ¯åæ¶è¿è¡æä½ã
å æ¤ï¼å ³äºçº¿ç¨åæ¥ï¼éè¦ç¢ç¢è®°ä½ç第ä¸ç¹æ¯ï¼çº¿ç¨åæ¥å°±æ¯çº¿ç¨æéãåæ¥å°±æ¯æéã线ç¨åæ¥çç®çå°±æ¯é¿å 线ç¨âåæ¥âæ§è¡ãè¿å¯çæ¯ä¸ªæ èçç»å£ä»¤ã
å ³äºçº¿ç¨åæ¥ï¼éè¦ç¢ç¢è®°ä½ç第äºç¹æ¯ âå ±äº«âè¿ä¸¤ä¸ªåãåªæå ±äº«èµæºç读å访é®æéè¦åæ¥ãå¦æä¸æ¯å ±äº«èµæºï¼é£ä¹å°±æ ¹æ¬æ²¡æåæ¥çå¿ è¦ã
å ³äºçº¿ç¨åæ¥ï¼éè¦ç¢ç¢è®°ä½ç第ä¸ç¹æ¯ï¼åªæâåéâæéè¦åæ¥è®¿é®ãå¦æå ±äº«çèµæºæ¯åºå®ä¸åçï¼é£ä¹å°±ç¸å½äºâ常éâï¼çº¿ç¨åæ¶è¯»å常éä¹ä¸éè¦åæ¥ãè³å°ä¸ä¸ªçº¿ç¨ä¿®æ¹å ±äº«èµæºï¼è¿æ ·çæ åµä¸ï¼çº¿ç¨ä¹é´å°±éè¦åæ¥ã
å ³äºçº¿ç¨åæ¥ï¼éè¦ç¢ç¢è®°ä½ç第åç¹æ¯ï¼å¤ä¸ªçº¿ç¨è®¿é®å ±äº«èµæºç代ç æå¯è½æ¯åä¸ä»½ä»£ç ï¼ä¹æå¯è½æ¯ä¸åç代ç ï¼æ 论æ¯å¦æ§è¡åä¸ä»½ä»£ç ï¼åªè¦è¿äºçº¿ç¨ç代ç 访é®åä¸ä»½å¯åçå ±äº«èµæºï¼è¿äºçº¿ç¨ä¹é´å°±éè¦åæ¥ã
为äºå æ·±ç解ï¼ä¸é¢ä¸¾å 个ä¾åã
æ两个éè´åï¼ä»ä»¬çå·¥ä½å 容æ¯ç¸åçï¼é½æ¯éµå¾ªå¦ä¸çæ¥éª¤ï¼
ï¼1ï¼å°å¸åºä¸å»ï¼å¯»æ¾å¹¶è´ä¹°ææ½åçæ ·åã
ï¼2ï¼åå°å ¬å¸ï¼åæ¥åã
è¿ä¸¤ä¸ªäººçå·¥ä½å 容è½ç¶ä¸æ ·ï¼ä»ä»¬é½éè¦è´ä¹°æ ·åï¼ä»ä»¬å¯è½ä¹°å°åæ ·ç§ç±»çæ ·åï¼ä½æ¯ä»ä»¬ç»å¯¹ä¸ä¼è´ä¹°å°åä¸ä»¶æ ·åï¼ä»ä»¬ä¹é´æ²¡æä»»ä½å ±äº«èµæºãæ以ï¼ä»ä»¬å¯ä»¥åèªè¿è¡èªå·±çå·¥ä½ï¼äºä¸å¹²æ°ã
è¿ä¸¤ä¸ªéè´åå°±ç¸å½äºä¸¤ä¸ªçº¿ç¨ï¼ä¸¤ä¸ªéè´åéµå¾ªç¸åçå·¥ä½æ¥éª¤ï¼ç¸å½äºè¿ä¸¤ä¸ªçº¿ç¨æ§è¡åä¸æ®µä»£ç ã
ä¸é¢ç»è¿ä¸¤ä¸ªéè´åå¢å ä¸ä¸ªå·¥ä½æ¥éª¤ãéè´åéè¦æ ¹æ®å ¬å¸çâå¸åæ âä¸é¢å ¬å¸çä¿¡æ¯ï¼å®æèªå·±çå·¥ä½è®¡åã
è¿ä¸¤ä¸ªéè´åæå¯è½åæ¶èµ°å°å¸åæ çåé¢ï¼åæ¶è§çå¸åæ ä¸çä¿¡æ¯ãè¿ä¸ç¹é®é¢é½æ²¡æãå 为å¸åæ æ¯åªè¯»çï¼è¿ä¸¤ä¸ªéè´åè°é½ä¸ä¼å»ä¿®æ¹å¸åæ ä¸åçä¿¡æ¯ã
ä¸é¢å¢å ä¸ä¸ªè§è²ãä¸ä¸ªåå ¬å®¤è¡æ¿äººåè¿ä¸ªæ¶åï¼ä¹èµ°å°äºå¸åæ åé¢ï¼åå¤ä¿®æ¹å¸åæ ä¸çä¿¡æ¯ã
å¦æè¡æ¿äººåå å°è¾¾å¸åæ ï¼å¹¶ä¸æ£å¨ä¿®æ¹å¸åæ çå 容ã两个éè´åè¿ä¸ªæ¶åï¼æ°å¥½ä¹å°äºãè¿ä¸¤ä¸ªéè´åå°±å¿ é¡»çå¾ è¡æ¿äººåå®æä¿®æ¹ä¹åï¼æè½è§çä¿®æ¹åçä¿¡æ¯ã
å¦æè¡æ¿äººåå°è¾¾çæ¶åï¼ä¸¤ä¸ªéè´åå·²ç»å¨è§çå¸åæ äºãé£ä¹è¡æ¿äººåéè¦çå¾ ä¸¤ä¸ªéè´åæå½åä¿¡æ¯è®°å½ä¸æ¥ä¹åï¼æè½å¤åä¸æ°çä¿¡æ¯ã
ä¸è¿°è¿ä¸¤ç§æ åµï¼è¡æ¿äººååéè´å对å¸åæ ç访é®å°±éè¦è¿è¡åæ¥ãå ä¸ºå ¶ä¸ä¸ä¸ªçº¿ç¨ï¼è¡æ¿äººåï¼ä¿®æ¹äºå ±äº«èµæºï¼å¸åæ ï¼ãèä¸æ们å¯ä»¥çå°ï¼è¡æ¿äººåçå·¥ä½æµç¨åéè´åçå·¥ä½æµç¨ï¼æ§è¡ä»£ç ï¼å®å ¨ä¸åï¼ä½æ¯ç±äºä»ä»¬è®¿é®äºåä¸ä»½å¯åå ±äº«èµæºï¼å¸åæ ï¼ï¼æ以ä»ä»¬ä¹é´éè¦åæ¥ã
åæ¥é
åé¢è®²äºä¸ºä»ä¹è¦çº¿ç¨åæ¥ï¼ä¸é¢æ们就æ¥çå¦ä½æè½çº¿ç¨åæ¥ã
线ç¨åæ¥çåºæ¬å®ç°æè·¯è¿æ¯æ¯è¾å®¹æç解çãæ们å¯ä»¥ç»å ±äº«èµæºå ä¸æéï¼è¿æéåªæä¸æé¥åãåªä¸ªçº¿ç¨è·åäºè¿æé¥åï¼æææå©è®¿é®è¯¥å ±äº«èµæºã
çæ´»ä¸ï¼æ们ä¹å¯è½ä¼éå°è¿æ ·çä¾åãä¸äºè¶ å¸çå¤é¢æä¾äºä¸äºèªå¨å¨ç©ç®±ãæ¯ä¸ªå¨ç©ç®±é½æä¸æéï¼ä¸æé¥åã人们å¯ä»¥ä½¿ç¨é£äºå¸¦æé¥åçå¨ç©ç®±ï¼æä¸è¥¿æ¾å°å¨ç©ç®±éé¢ï¼æå¨ç©ç®±éä¸ï¼ç¶åæé¥åæ¿èµ°ãè¿æ ·ï¼è¯¥å¨ç©ç®±å°±è¢«éä½äºï¼å ¶ä»äººä¸è½å访é®è¿ä¸ªå¨ç©ç®±ãï¼å½ç¶ï¼çå®çå¨ç©ç®±é¥åæ¯å¯ä»¥è¢«äººæ¿èµ°å¤å¶çï¼æ以ä¸è¦æè´µéç©åæ¾å¨è¶ å¸çå¨ç©ç®±éé¢ãäºæ¯å¾å¤è¶ å¸é½éç¨äºçµåå¯ç éãï¼
线ç¨åæ¥éè¿ä¸ªæ¨¡åçèµ·æ¥å¾ç´è§ãä½æ¯ï¼è¿æä¸ä¸ªä¸¥å³»çé®é¢æ²¡æ解å³ï¼è¿ä¸ªåæ¥éåºè¯¥å å¨åªéï¼
å½ç¶æ¯å å¨å ±äº«èµæºä¸äºãååºå¿«ç读è ä¸å®ä¼æ¢å åçã
没éï¼å¦æå¯è½ï¼æ们å½ç¶å°½éæåæ¥éå å¨å ±äº«èµæºä¸ãä¸äºæ¯è¾å®åçå ±äº«èµæºï¼æ¯å¦ï¼æ件系ç»ï¼æ°æ®åºç³»ç»çï¼èªèº«é½æä¾äºæ¯è¾å®åçåæ¥éæºå¶ãæ们ä¸ç¨å¦å¤ç»è¿äºèµæºå éï¼è¿äºèµæºèªå·±å°±æéã
ä½æ¯ï¼å¤§é¨åæ åµä¸ï¼æ们å¨ä»£ç ä¸è®¿é®çå ±äº«èµæºé½æ¯æ¯è¾ç®åçå ±äº«å¯¹è±¡ãè¿äºå¯¹è±¡éé¢æ²¡æå°æ¹è®©æ们å éã
读è å¯è½ä¼æåºå»ºè®®ï¼ä¸ºä»ä¹ä¸å¨æ¯ä¸ä¸ªå¯¹è±¡å é¨é½å¢å ä¸ä¸ªæ°çåºåï¼ä¸é¨ç¨æ¥å éå¢ï¼è¿ç§è®¾è®¡ç论ä¸å½ç¶ä¹æ¯å¯è¡çãé®é¢å¨äºï¼çº¿ç¨åæ¥çæ åµå¹¶ä¸æ¯å¾æ®éãå¦æå 为è¿å°æ¦çäºä»¶ï¼å¨ææ对象å é¨é½å¼è¾ä¸åé空é´ï¼å°ä¼å¸¦æ¥æ大ç空é´æµªè´¹ãå¾ä¸å¿å¤±ã
äºæ¯ï¼ç°ä»£çç¼ç¨è¯è¨ç设计æè·¯é½æ¯æåæ¥éå å¨ä»£ç 段ä¸ãç¡®åç说ï¼æ¯æåæ¥éå å¨â访é®å ±äº«èµæºç代ç 段âä¸ãè¿ä¸ç¹ä¸å®è¦è®°ä½ï¼åæ¥éæ¯å å¨ä»£ç 段ä¸çã
åæ¥éå å¨ä»£ç 段ä¸ï¼å°±å¾å¥½å°è§£å³äºä¸è¿°ç空é´æµªè´¹é®é¢ãä½æ¯å´å¢å äºæ¨¡åçå¤æ度ï¼ä¹å¢å äºæ们çç解é¾åº¦ã
ç°å¨æ们就æ¥ä»ç»åæâåæ¥éå å¨ä»£ç 段ä¸âç线ç¨åæ¥æ¨¡åã
é¦å ï¼æ们已ç»è§£å³äºåæ¥éå å¨åªéçé®é¢ãæ们已ç»ç¡®å®ï¼åæ¥éä¸æ¯å å¨å ±äº«èµæºä¸ï¼èæ¯å å¨è®¿é®å ±äº«èµæºç代ç 段ä¸ã
å ¶æ¬¡ï¼æ们è¦è§£å³çé®é¢æ¯ï¼æ们åºè¯¥å¨ä»£ç 段ä¸å ä»ä¹æ ·çéãè¿ä¸ªé®é¢æ¯éç¹ä¸çéç¹ãè¿æ¯æä»¬å°¤å ¶è¦æ³¨æçé®é¢ï¼è®¿é®åä¸ä»½å ±äº«èµæºçä¸å代ç 段ï¼åºè¯¥å ä¸åä¸ä¸ªåæ¥éï¼å¦æå çæ¯ä¸åçåæ¥éï¼é£ä¹æ ¹æ¬å°±èµ·ä¸å°åæ¥çä½ç¨ï¼æ²¡æä»»ä½æä¹ã
è¿å°±æ¯è¯´ï¼åæ¥éæ¬èº«ä¹ä¸å®æ¯å¤ä¸ªçº¿ç¨ä¹é´çå ±äº«å¯¹è±¡ã
Javaè¯è¨çsynchronizedå ³é®å
为äºå æ·±ç解ï¼ä¸¾å 个代ç 段åæ¥çä¾åã
ä¸åè¯è¨çåæ¥é模åé½æ¯ä¸æ ·çãåªæ¯è¡¨è¾¾æ¹å¼æäºä¸åãè¿éæ们以å½åææµè¡çJavaè¯è¨ä¸ºä¾ãJavaè¯è¨éé¢ç¨synchronizedå ³é®åç»ä»£ç 段å éãæ´ä¸ªè¯æ³å½¢å¼è¡¨ç°ä¸º
synchronized(åæ¥é) {
// 访é®å ±äº«èµæºï¼éè¦åæ¥ç代ç 段
}
è¿éå°¤å ¶è¦æ³¨æçå°±æ¯ï¼åæ¥éæ¬èº«ä¸å®è¦æ¯å ±äº«ç对象ã
⦠f1() {
Object lock1 = new Object(); // 产çä¸ä¸ªåæ¥é
synchronized(lock1){
// 代ç 段 A
// 访é®å ±äº«èµæº resource1
// éè¦åæ¥
}
}
ä¸é¢è¿æ®µä»£ç 没æä»»ä½æä¹ãå 为é£ä¸ªåæ¥éæ¯å¨å½æ°ä½å é¨äº§ççãæ¯ä¸ªçº¿ç¨è°ç¨è¿æ®µä»£ç çæ¶åï¼é½ä¼äº§çä¸ä¸ªæ°çåæ¥éãé£ä¹å¤ä¸ªçº¿ç¨ä¹é´ï¼ä½¿ç¨çæ¯ä¸åçåæ¥éãæ ¹æ¬è¾¾ä¸å°åæ¥çç®çã
åæ¥ä»£ç ä¸å®è¦åæå¦ä¸çå½¢å¼ï¼æææä¹ã
public static final Object lock1 = new Object();
⦠f1() {
synchronized(lock1){ // lock1 æ¯å ¬ç¨åæ¥é
// 代ç 段 A
// 访é®å ±äº«èµæº resource1
// éè¦åæ¥
}
ä½ ä¸ä¸å®è¦æåæ¥é声æ为staticæè publicï¼ä½æ¯ä½ ä¸å®è¦ä¿è¯ç¸å ³çåæ¥ä»£ç ä¹é´ï¼ä¸å®è¦ä½¿ç¨åä¸ä¸ªåæ¥éã
讲å°è¿éï¼ä½ ä¸å®ä¼å¥½å¥ï¼è¿ä¸ªåæ¥éå°åºæ¯ä¸ªä»ä¹ä¸è¥¿ã为ä»ä¹é便声æä¸ä¸ªObject对象ï¼å°±å¯ä»¥ä½ä¸ºåæ¥éï¼
å¨Javaéé¢ï¼åæ¥éçæ¦å¿µå°±æ¯è¿æ ·çãä»»ä½ä¸ä¸ªObject Referenceé½å¯ä»¥ä½ä¸ºåæ¥éãæ们å¯ä»¥æObject Referenceç解为对象å¨å ååé ç³»ç»ä¸çå åå°åãå æ¤ï¼è¦ä¿è¯åæ¥ä»£ç 段ä¹é´ä½¿ç¨çæ¯åä¸ä¸ªåæ¥éï¼æ们就è¦ä¿è¯è¿äºåæ¥ä»£ç 段çsynchronizedå ³é®å使ç¨çæ¯åä¸ä¸ªObject Referenceï¼åä¸ä¸ªå åå°åãè¿ä¹æ¯ä¸ºä»ä¹æå¨åé¢ç代ç ä¸å£°ælock1çæ¶åï¼ä½¿ç¨äºfinalå ³é®åï¼è¿å°±æ¯ä¸ºäºä¿è¯lock1çObject Referenceå¨æ´ä¸ªç³»ç»è¿è¡è¿ç¨ä¸é½ä¿æä¸åã
ä¸äºæ±ç¥æ¬²å¼ºç读è å¯è½æ³è¦ç»§ç»æ·±å ¥äºè§£synchronzied(åæ¥é)çå®é è¿è¡æºå¶ãJavaèææºè§èä¸ï¼ä½ å¯ä»¥å¨googleç¨âJVM Specâçå ³é®åè¿è¡æç´¢ï¼ï¼æ对synchronizedå ³é®åç详ç»è§£éãsynchronizedä¼ç¼è¯æ monitor enter, ⦠monitor exitä¹ç±»çæ令对ãMonitorå°±æ¯å®é ä¸çåæ¥éãæ¯ä¸ä¸ªObject Referenceå¨æ¦å¿µä¸é½å¯¹åºä¸ä¸ªmonitorã
è¿äºå®ç°ç»èé®é¢ï¼å¹¶ä¸æ¯ç解åæ¥é模åçå ³é®ãæ们继ç»çå 个ä¾åï¼å 深对åæ¥é模åçç解ã
public static final Object lock1 = new Object();
⦠f1() {
synchronized(lock1){ // lock1 æ¯å ¬ç¨åæ¥é
// 代ç 段 A
// 访é®å ±äº«èµæº resource1
// éè¦åæ¥
}
}
⦠f2() {
synchronized(lock1){ // lock1 æ¯å ¬ç¨åæ¥é
// 代ç 段 B
// 访é®å ±äº«èµæº resource1
// éè¦åæ¥
}
}
ä¸è¿°ç代ç ä¸ï¼ä»£ç 段Aå代ç 段Bå°±æ¯åæ¥çãå 为å®ä»¬ä½¿ç¨çæ¯åä¸ä¸ªåæ¥élock1ã
å¦ææ个线ç¨åæ¶æ§è¡ä»£ç 段Aï¼åæ¶è¿æ个线ç¨åæ¶æ§è¡ä»£ç 段Bï¼é£ä¹è¿ä¸ªçº¿ç¨ä¹é´é½æ¯è¦è¿è¡åæ¥çã
è¿ä¸ªçº¿ç¨é½è¦ç«äºä¸ä¸ªåæ¥élock1ãåä¸æ¶å»ï¼åªæä¸ä¸ªçº¿ç¨è½å¤è·å¾lock1çæææï¼åªæä¸ä¸ªçº¿ç¨å¯ä»¥æ§è¡ä»£ç 段Aæè 代ç 段Bãå ¶ä»ç«äºå¤±è´¥ç线ç¨åªè½æåè¿è¡ï¼è¿å ¥å°è¯¥åæ¥éç就绪ï¼Readyï¼éåã
æ¯ä¸ä¸ªåæ¥éä¸é¢é½æäºå 个线ç¨éåï¼å æ¬å°±ç»ªï¼Readyï¼éåï¼å¾ å¬ï¼Waitingï¼éåçãæ¯å¦ï¼lock1对åºç就绪éåå°±å¯ä»¥å«ålock1 - ready queueãæ¯ä¸ªéåéé¢é½å¯è½æå¤ä¸ªæåè¿è¡ç线ç¨ã
注æï¼ç«äºåæ¥é失败ç线ç¨è¿å ¥çæ¯è¯¥åæ¥éç就绪ï¼Readyï¼éåï¼èä¸æ¯åé¢è¦è®²è¿°çå¾ å¬éåï¼Waiting Queueï¼ä¹å¯ä»¥ç¿»è¯ä¸ºçå¾ éåï¼ã就绪éåéé¢ç线ç¨æ»æ¯æ¶å»åå¤çç«äºåæ¥éï¼æ¶å»åå¤çè¿è¡ãèå¾ å¬éåéé¢ç线ç¨ååªè½ä¸ç´çå¾ ï¼ç´å°çå°æ个信å·çéç¥ä¹åï¼æè½å¤è½¬ç§»å°å°±ç»ªéåä¸ï¼åå¤è¿è¡ã
æåè·ååæ¥éç线ç¨ï¼æ§è¡å®åæ¥ä»£ç 段ä¹åï¼ä¼éæ¾åæ¥éã该åæ¥éç就绪éåä¸çå ¶ä»çº¿ç¨å°±ç»§ç»ä¸ä¸è½®åæ¥éçç«äºãæåè å°±å¯ä»¥ç»§ç»è¿è¡ï¼å¤±è´¥è è¿æ¯è¦ä¹ä¹å°å¾ å¨å°±ç»ªéåä¸ã
å æ¤ï¼çº¿ç¨åæ¥æ¯é常èè´¹èµæºçä¸ç§æä½ãæ们è¦å°½éæ§å¶çº¿ç¨åæ¥ç代ç 段èå´ãåæ¥ç代ç 段èå´è¶å°è¶å¥½ãæ们ç¨ä¸ä¸ªåè¯âåæ¥ç²åº¦âæ¥è¡¨ç¤ºåæ¥ä»£ç 段çèå´ã
åæ¥ç²åº¦
å¨Javaè¯è¨éé¢ï¼æ们å¯ä»¥ç´æ¥æsynchronizedå ³é®åç´æ¥å å¨å½æ°çå®ä¹ä¸ã
æ¯å¦ã
⦠synchronized ⦠f1() {
// f1 代ç 段
}
è¿æ®µä»£ç å°±çä»·äº
⦠f1() {
synchronized(this){ // åæ¥éå°±æ¯å¯¹è±¡æ¬èº«
// f1 代ç 段
}
}
åæ ·çååéç¨äºéæï¼staticï¼å½æ°
æ¯å¦ã
⦠static synchronized ⦠f1() {
// f1 代ç 段
}
è¿æ®µä»£ç å°±çä»·äº
â¦static ⦠f1() {
synchronized(Class.forName(â¦)){ // åæ¥éæ¯ç±»å®ä¹æ¬èº«
// f1 代ç 段
}
}
ä½æ¯ï¼æ们è¦å°½éé¿å è¿ç§ç´æ¥æsynchronizedå å¨å½æ°å®ä¹ä¸çå·æåæ³ãå 为æ们è¦æ§å¶åæ¥ç²åº¦ãåæ¥ç代ç 段è¶å°è¶å¥½ãsynchronizedæ§å¶çèå´è¶å°è¶å¥½ã
æ们ä¸ä» è¦å¨ç¼©å°åæ¥ä»£ç 段çé¿åº¦ä¸ä¸å夫ï¼æ们åæ¶è¿è¦æ³¨æç»ååæ¥éã
æ¯å¦ï¼ä¸é¢ç代ç
public static final Object lock1 = new Object();
⦠f1() {
synchronized(lock1){ // lock1 æ¯å ¬ç¨åæ¥é
// 代ç 段 A
// 访é®å ±äº«èµæº resource1
// éè¦åæ¥
}
}
⦠f2() {
synchronized(lock1){ // lock1 æ¯å ¬ç¨åæ¥é
// 代ç 段 B
// 访é®å ±äº«èµæº resource1
// éè¦åæ¥
}
}
⦠f3() {
synchronized(lock1){ // lock1 æ¯å ¬ç¨åæ¥é
// 代ç 段 C
// 访é®å ±äº«èµæº resource2
// éè¦åæ¥
}
}
⦠f4() {
synchronized(lock1){ // lock1 æ¯å ¬ç¨åæ¥é
// 代ç 段 D
// 访é®å ±äº«èµæº resource2
// éè¦åæ¥
}
}
ä¸è¿°ç4段åæ¥ä»£ç ï¼ä½¿ç¨åä¸ä¸ªåæ¥élock1ãææè°ç¨4段代ç ä¸ä»»ä½ä¸æ®µä»£ç ç线ç¨ï¼é½éè¦ç«äºåä¸ä¸ªåæ¥élock1ã
æ们ä»ç»åæä¸ä¸ï¼åç°è¿æ¯æ²¡æå¿ è¦çã
å 为f1()ç代ç 段Aåf2()ç代ç 段B访é®çå ±äº«èµæºæ¯resource1ï¼f3()ç代ç 段Cåf4()ç代ç 段D访é®çå ±äº«èµæºæ¯resource2ï¼å®ä»¬æ²¡æå¿ è¦é½ç«äºåä¸ä¸ªåæ¥élock1ãæ们å¯ä»¥å¢å ä¸ä¸ªåæ¥élock2ãf3()åf4()ç代ç å¯ä»¥ä¿®æ¹ä¸ºï¼
public static final Object lock2 = new Object();
⦠f3() {
synchronized(lock2){ // lock2 æ¯å ¬ç¨åæ¥é
// 代ç 段 C
// 访é®å ±äº«èµæº resource2
// éè¦åæ¥
}
}
⦠f4() {
synchronized(lock2){ // lock2 æ¯å ¬ç¨åæ¥é
// 代ç 段 D
// 访é®å ±äº«èµæº resource2
// éè¦åæ¥
}
}
è¿æ ·ï¼f1()åf2()å°±ä¼ç«äºlock1ï¼èf3()åf4()å°±ä¼ç«äºlock2ãè¿æ ·ï¼åå¼æ¥åå«ç«äºä¸¤ä¸ªéï¼å°±å¯ä»¥å¤§å¤§è¾å°åæ¥éç«äºçæ¦çï¼ä»èåå°ç³»ç»çå¼éã
ä¿¡å·é
åæ¥é模ååªæ¯æç®åçåæ¥æ¨¡åãåä¸æ¶å»ï¼åªæä¸ä¸ªçº¿ç¨è½å¤è¿è¡åæ¥ä»£ç ã
æçæ¶åï¼æ们å¸æå¤çæ´å å¤æçåæ¥æ¨¡åï¼æ¯å¦ç产è /æ¶è´¹è 模åã读ååæ¥æ¨¡åçãè¿ç§æ åµä¸ï¼åæ¥é模åå°±ä¸å¤ç¨äºãæ们éè¦ä¸ä¸ªæ°ç模åãè¿å°±æ¯æ们è¦è®²è¿°çä¿¡å·é模åã
ä¿¡å·é模åçå·¥ä½æ¹å¼å¦ä¸ï¼çº¿ç¨å¨è¿è¡çè¿ç¨ä¸ï¼å¯ä»¥ä¸»å¨åä¸æ¥ï¼çå¾ æ个信å·éçéç¥ï¼è¿æ¶åï¼è¯¥çº¿ç¨å°±è¿å ¥å°è¯¥ä¿¡å·éçå¾ å¬ï¼Waitingï¼éåå½ä¸ï¼çå°éç¥ä¹åï¼å继ç»è¿è¡ã
å¾å¤è¯è¨éé¢ï¼åæ¥éé½ç±ä¸é¨ç对象表示ï¼å¯¹è±¡åé常å«Monitorã
åæ ·ï¼å¨å¾å¤è¯è¨ä¸ï¼ä¿¡å·éé常ä¹æä¸é¨ç对象åæ¥è¡¨ç¤ºï¼æ¯å¦ï¼Mutexï¼Semphoreã
ä¿¡å·é模åè¦æ¯åæ¥é模åå¤æ许å¤ãä¸äºç³»ç»ä¸ï¼ä¿¡å·éçè³å¯ä»¥è·¨è¿ç¨è¿è¡åæ¥ãå¦å¤ä¸äºä¿¡å·éçè³è¿æ计æ°åè½ï¼è½å¤æ§å¶åæ¶è¿è¡ç线ç¨æ°ã
æ们没æå¿ è¦èèé£ä¹å¤æç模åãææé£äºå¤æç模åï¼é½æ¯æåºæ¬ç模åè¡çåºæ¥çãåªè¦ææ¡äºæåºæ¬çä¿¡å·é模åâââçå¾ /éç¥â模åï¼å¤æ模åä¹å°±è¿åè解äºã
æ们è¿æ¯ä»¥Javaè¯è¨ä¸ºä¾ãJavaè¯è¨éé¢çåæ¥éåä¿¡å·éæ¦å¿µé½é常模ç³ï¼æ²¡æä¸é¨ç对象åè¯æ¥è¡¨ç¤ºåæ¥éåä¿¡å·éï¼åªæ两个åæ¥éç¸å ³çå ³é®åââvolatileåsynchronizedã
è¿ç§æ¨¡ç³è½ç¶å¯¼è´æ¦å¿µä¸æ¸ ï¼ä½åæ¶ä¹é¿å äºMonitorãMutexãSemphoreçåè¯å¸¦æ¥çç§ç§è¯¯è§£ãæ们ä¸å¿ æ§çäºåè¯ä¹äºï¼å¯ä»¥ä¸æ³¨äºç解å®é çè¿è¡åçã
å¨Javaè¯è¨éé¢ï¼ä»»ä½ä¸ä¸ªObject Referenceé½å¯ä»¥ä½ä¸ºåæ¥éãåæ ·çéçï¼ä»»ä½ä¸ä¸ªObject Referenceä¹å¯ä»¥ä½ä¸ºä¿¡å·éã
Object对象çwait()æ¹æ³å°±æ¯çå¾ éç¥ï¼Object对象çnotify()æ¹æ³å°±æ¯ååºéç¥ã
å ·ä½è°ç¨æ¹æ³ä¸º
ï¼1ï¼çå¾ æ个信å·éçéç¥
public static final Object signal = new Object();
⦠f1() {
synchronized(singal) { // é¦å æ们è¦è·åè¿ä¸ªä¿¡å·éãè¿ä¸ªä¿¡å·éåæ¶ä¹æ¯ä¸ä¸ªåæ¥é
// åªææåè·åäºsignalè¿ä¸ªä¿¡å·éå ¼åæ¥éä¹åï¼æ们æå¯è½è¿å ¥è¿æ®µä»£ç
signal.wait(); // è¿éè¦æ¾å¼ä¿¡å·éãæ¬çº¿ç¨è¦è¿å ¥signalä¿¡å·éçå¾ å¬ï¼Waitingï¼éå
// å¯æãè¾è¾è¦è¦äºåå°æçä¿¡å·éï¼å°±è¿ä¹è¢«æ¾å¼äº
// çå°éç¥ä¹åï¼ä»å¾ å¬ï¼Waitingï¼éå转å°å°±ç»ªï¼Readyï¼éåéé¢
// 转å°äºå°±ç»ªéåä¸ï¼ç¦»CPUæ ¸å¿è¿äºä¸æ¥ï¼å°±ææºä¼ç»§ç»æ§è¡ä¸é¢ç代ç äºã
// ä»ç¶éè¦æsignalåæ¥éç«äºå°æï¼æè½å¤çæ£ç»§ç»æ§è¡ä¸é¢ç代ç ãå½è¦åã
â¦
}
}
éè¦æ³¨æçæ¯ï¼ä¸è¿°ä»£ç ä¸çsignal.wait()çææãsignal.wait()å¾å®¹æ导è´è¯¯è§£ãsignal.wait()çææ并ä¸æ¯è¯´ï¼signalå¼å§waitï¼èæ¯è¯´ï¼è¿è¡è¿æ®µä»£ç çå½å线ç¨å¼å§waitè¿ä¸ªsignal对象ï¼å³è¿å ¥signal对象çå¾ å¬ï¼Waitingï¼éåã
ï¼2ï¼ååºæ个信å·éçéç¥
⦠f2() {
synchronized(singal) { // é¦å ï¼æ们åæ ·è¦è·åè¿ä¸ªä¿¡å·éãåæ¶ä¹æ¯ä¸ä¸ªåæ¥éã
// åªææåè·åäºsignalè¿ä¸ªä¿¡å·éå ¼åæ¥éä¹åï¼æ们æå¯è½è¿å ¥è¿æ®µä»£ç
signal.notify(); // è¿éï¼æ们éç¥signalçå¾ å¬éåä¸çæ个线ç¨ã
// å¦ææ个线ç¨çå°äºè¿ä¸ªéç¥ï¼é£ä¸ªçº¿ç¨å°±ä¼è½¬å°å°±ç»ªéåä¸
// ä½æ¯æ¬çº¿ç¨ä»ç¶ç»§ç»æ¥æsignalè¿ä¸ªåæ¥éï¼æ¬çº¿ç¨ä»ç¶ç»§ç»æ§è¡
// å¿å¿ï¼è½ç¶æ¬çº¿ç¨å¥½å¿éç¥å ¶ä»çº¿ç¨ï¼
// ä½æ¯ï¼æ¬çº¿ç¨å¯æ²¡æé£ä¹é«é£äº®èï¼æ¾å¼å°æçåæ¥é
// æ¬çº¿ç¨ç»§ç»æ§è¡ä¸é¢ç代ç
â¦
}
}
éè¦æ³¨æçæ¯ï¼signal.notify()çææãsignal.notify()并ä¸æ¯éç¥signalè¿ä¸ªå¯¹è±¡æ¬èº«ãèæ¯éç¥æ£å¨çå¾ signalä¿¡å·éçå ¶ä»çº¿ç¨ã
以ä¸å°±æ¯Objectçwait()ånotify()çåºæ¬ç¨æ³ã
å®é ä¸ï¼wait()è¿å¯ä»¥å®ä¹çå¾ æ¶é´ï¼å½çº¿ç¨å¨æä¿¡å·éçå¾ å¬éåä¸ï¼çå°è¶³å¤é¿çæ¶é´ï¼å°±ä¼çæ å¯çï¼æ éåçï¼èªå·±å°±ä»å¾ å¬éå转移å°å°±ç»ªéåä¸äºã
å¦å¤ï¼è¿æä¸ä¸ªnotifyAll()æ¹æ³ï¼è¡¨ç¤ºéç¥å¾ å¬éåéé¢çææ线ç¨ã
è¿äºç»èé®é¢ï¼å¹¶ä¸å¯¹å¤§å±äº§çå½±åã
绿è²çº¿ç¨
绿è²çº¿ç¨ï¼Green Threadï¼æ¯ä¸ä¸ªç¸å¯¹äºæä½ç³»ç»çº¿ç¨ï¼Native Threadï¼çæ¦å¿µã
æä½ç³»ç»çº¿ç¨ï¼Native Threadï¼çææå°±æ¯ï¼ç¨åºéé¢ç线ç¨ä¼çæ£æ å°å°æä½ç³»ç»ç线ç¨ï¼çº¿ç¨çè¿è¡åè°åº¦é½æ¯ç±æä½ç³»ç»æ§å¶ç
绿è²çº¿ç¨ï¼Green Threadï¼çæææ¯ï¼ç¨åºéé¢ç线ç¨ä¸ä¼çæ£æ å°å°æä½ç³»ç»ç线ç¨ï¼èæ¯ç±è¯è¨è¿è¡å¹³å°èªèº«æ¥è°åº¦ã
å½åçæ¬çPythonè¯è¨ç线ç¨å°±å¯ä»¥æ å°å°æä½ç³»ç»çº¿ç¨ãå½åçæ¬çRubyè¯è¨ç线ç¨å°±å±äºç»¿è²çº¿ç¨ï¼æ æ³æ å°å°æä½ç³»ç»ç线ç¨ï¼å æ¤Rubyè¯è¨ç线ç¨çè¿è¡é度æ¯è¾æ ¢ã
é¾é说ï¼ç»¿è²çº¿ç¨è¦æ¯æä½ç³»ç»çº¿ç¨è¦æ ¢åï¼å½ç¶ä¸æ¯è¿æ ·ãäºå®ä¸ï¼æ åµå¯è½æ£å¥½ç¸åãRubyæ¯ä¸ä¸ªç¹æ®çä¾åã线ç¨è°åº¦å¨å¹¶ä¸æ¯å¾æçã
ç®åï¼çº¿ç¨çæµè¡å®ç°æ¨¡åå°±æ¯ç»¿è²çº¿ç¨ãæ¯å¦ï¼stackless Pythonï¼å°±å¼å ¥äºæ´å è½»éç绿è²çº¿ç¨æ¦å¿µãå¨çº¿ç¨å¹¶åç¼ç¨æ¹é¢ï¼æ 论æ¯è¿è¡é度è¿æ¯å¹¶åè´è½½ä¸ï¼é½ä¼äºPythonã
å¦ä¸ä¸ªæ´èåçä¾åå°±æ¯ErLangï¼ç±ç«ä¿¡å ¬å¸å¼åçä¸ç§å¼æºè¯è¨ï¼ã
ErLangç绿è²çº¿ç¨æ¦å¿µé常彻åºãErLangç线ç¨ä¸å«Threadï¼èæ¯å«åProcessãè¿å¾å®¹æåè¿ç¨æ··æ·èµ·æ¥ãè¿éè¦æ³¨æåºåä¸ä¸ã
ErLang Processä¹é´æ ¹æ¬å°±ä¸éè¦åæ¥ãå 为ErLangè¯è¨çææåéé½æ¯finalçï¼ä¸å 许åéçå¼åçä»»ä½ååãå æ¤æ ¹æ¬å°±ä¸éè¦åæ¥ã
finalåéçå¦ä¸ä¸ªå¥½å¤å°±æ¯ï¼å¯¹è±¡ä¹é´ä¸å¯è½åºç°äº¤åå¼ç¨ï¼ä¸å¯è½ææä¸ç§ç¯ç¶çå ³èï¼å¯¹è±¡ä¹é´çå ³èé½æ¯ååçï¼æ ç¶çãå æ¤ï¼å ååå¾åæ¶çç®æ³æçä¹é常é«ãè¿å°±è®©ErLangè½å¤è¾¾å°Soft Real Timeï¼è½¯å®æ¶ï¼çææãè¿å¯¹äºä¸é¨æ¯æå ååå¾åæ¶çè¯è¨æ¥è¯´ï¼å¯ä¸æ¯ä¸ä»¶å®¹æçäºæ ã
Java多线程——singleThreadExecutor
singleThreadExecutor,Java中Executors类的一个静态方法,创建了一个线程池,该线程池仅包含一个核心线程。这意味着所有任务将由这一单一线程执行,形成单线程执行模式。若核心线程因异常停止,则将启动新的线程替代,确保服务不中断。此线程池特别设计确保任务执行顺序与提交顺序一致,提升程序执行流程的可预测性与稳定性。
创建singleThreadExecutor的代码示例如下:
在这个例子中,ThreadPoolExecutor的corePoolSize和maximumPoolSize的值均为1,明确指出线程池仅包含一个核心线程,且最大线程数同样为1,保证了线程的高效利用。缓冲队列采用的是LinkedBlockingQueue,这是一个无边界队列,用于存储等待执行的任务。