ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java多线程:在看源码之前,更建议掌握的知识

Java多线程:在看源码之前,更建议掌握的知识 接触Java多线程编程多了后大家也许会发现无论是Thread的各种方法、JMM、JVM还是各种同步、锁等高大上的概念都是围绕着一个主题去开展的那就是并发设计。并发设计则是在指定系统或者单元中因资源有限出现资源冲突如CPU、内存为了解决这些问题让计算机的资源利用率更高、时间更节省而设计了针对性的解决方案这过程叫并发设计。一、程序与系统资源的交互可能上面文字太抽象了我们先从程序与系统资源的交互入手。了解多线程编程的人线程涉及最多的是CPU和内存。内存存放我们的程序数据CPU则给与我们处理数据的运算能力。那么我们的程序是怎样和两者产生关系的呢可能学习编程细节前我们掌握大致流程让我们更有方向性。1、我们的程序program也就是.java文件保持在硬盘中其由一行行代码指令组成。2、我们在装有jre环境的机器上通过javac编译成功后得到的.class文件通过java这个命令生成一个JVM实例并在其中运行程序生成一个进程Process。3、JVM实例为进程分配内存空间把数据对象放入到堆内存里面。这时候进程处于等待状态需要得到CPU时间片才能执行指令。4、一个进程会有若干个java线程应用级线程这些线程也是需要得到CPU使用权限CPU时间片才能执行其代码指令的。而线程之间也是轮流运行5、一个java线程与操作系统级线程内核线程进行一一映射就是说Java线程需要分配给一个内核线程。6、统筹内核线程和CPU之间的关联的是调度器scheduler,它也是操作系统的一部分。7、CPU执行时间被分为非常短的时间片大概20毫秒。调度器把具体的CPU时间片分配给内核线程每个CPU时间片只运行一个内核线程。8、当CPU时间片用完后而该内核线程还在运行的话调度器将剥夺该内核线程的CPU使用权并分配给其他就绪状态的内核线程。如果CPU时间片内内核线程工作结束或者进入阻塞则调度器把剩余的CPU时间片分配给其他内核线程。在日常开发中我们也许更关注程序层面的操作解决问题以查看代码、java源码以及调试JVM。但是如果我们能超越源码去掌握整个软硬件的交互流程那么对我们工作或者学习中全局观会更强。二、线程与内存、CPU我们知道当程序运行起来的时候就生成一个进程并分配到相应的内存空间主要是堆内存。进程内有若干个线程线程共享堆内存的数据同时线程也会向堆内存同步数据这样就产生了线程安全的问题了。因此锁等用于解决多线程并发导致线程不安全的机制也应运而生。线程是轮流执行的如何协调CPU时间片内各线程任务完成效率以及正确性是重点。Thread里面的join、sleep等方法就是用于协调各线程间在CPU时间片内任务完成而制定的。另外就是线程间的切换需要消耗CPU时间也成为上下文切换时间减少线程切换以及线程创建和销毁的耗时也一直在进行优化如线程池就是其一。三、并发设计案例还是以网上比较经典的泡茶例子讲述并发设计的流程。泡茶可以分为三个步骤煮水需10分钟洗茶具7分钟泡茶3分钟。这就把泡茶这个相对复杂的任务拆解成三个较为独立的三个小任务。然后按一个人去做这三件事相当于三个线程在等待CPU的使用权。根据前后置关系煮水、洗茶具必须在泡茶之前而洗茶具和煮水并没有必然的关联。我们假定煮水的步骤中只有接水和操作煮水需要人去做剩下的时间就等炉具把水烧开假定这步骤需要人的时间为2分钟剩下八分钟可以去干别的这个就类似线程sleep了八分钟。那么我们可以为这次泡茶工作设计如下三套方案以上三种方案都属于并发方案因为都是以固定的时间去完成任务只是最后一个体现出并行的效果从而提升了执行效率和节省时间。四、结语结合自己在学习多线程的经历开始是也是针对特定知识点逐个突破从了解概念、编码印证、读源码掌握java原生态的方法实现流程。就如下图从外围的做什么概念入手然后去看怎样做编码最后才明白为什么这样做。学了一段时间后发现多线程的各个主题主要围绕并发设计而定的在提升效率的同时并解决内存安全问题以及CPU时间的利用率。也就是从为什么这样做到怎样做在归纳这样做属于什么范畴线程池锁机制等。从一个模糊到清晰的过程理解所作的事情的意义并为目的去寻找方法最后得到了一个结果。这就是著名的黄金圈法则亲身经历的感觉是非常不错的大家不妨去试下。
返回列表