php源码建站 一品资源,无锡网站优化哪家快,鞍山58同城最新招聘信息,阿里指数app下载白话说编程之java线程线程和进程#xff1a;进程#xff1a;线程#xff1a;线程和进程的区别#xff1a;详解多线程:并发为什么使用并发并发的执行原理并行线程的五种状态#xff1a;创建状态#xff1a;就绪状态#xff1a;运行状态#xff1a;阻塞状态#xff1a;死…
白话说编程之java线程线程和进程进程线程线程和进程的区别详解多线程:并发为什么使用并发并发的执行原理并行线程的五种状态创建状态就绪状态运行状态阻塞状态死亡状态线程的创建方式继承Thread实现Runnable匿名内部类方式迷惑问题继承THread类方法和实现Runnable接口 这两种方式选择哪一种好呢继器启动线程是调用run方法还是start方法线程的分类用户线程也叫前台线程守护线程也叫后台线程分享一波:程序员赚外快-必看的巅峰干货线程和进程
在说多线程之前我们先来研究一下线程说到线程我们又不得不说到进程因为很多初学者会把线程和进程分不清搞混淆。
进程
是操作系统系统运行的最小单元。怎么理解这句话可以这样去对比相信大家都见过积木玩具可以搭建成很多的大型成品操作系统Windows/Linux等等而每一个积木都是组成这个成品的一个组件也就是进程单元这是操作系统和进程的关系操作系统的组成很复杂不是像积木简单的组合就能完成的但是最底层原理我们可以这么想象是没有问题的。
线程
线程是一组指令的集合它可以独立的运行在一个进程里。关于指令的集合就是指我们编程里写的一个类里面用到的关键字、方法名、变量名等等都是指令你们可以这样去理解完全没有问题这里声明一下真正的指令是jvm编译成.class文件后.class中的二进制码才是真正的指令但是二进制码对于人类来说太多太难记所以就用关键字来代表二进制的含义。在这里我们又可以把线程去当成一个积木而进程是一个个积木所组成的成品。
线程和进程的区别
通过上面的例子不难理解进程和线程之间的关系进程包含线程线程是进程的一个单元。所以在这里我们要注意一下在进程中至少包含一个线程主线程。这样讲一个积木都没有还会有成品吗
总结:进程是所有线程的集合每一个线程是进程中的一条执行路径。
详解多线程:
在上面的例子中我们知道线程和进程的区别,对于多线程的具体作用我们在这里详细解释。
并发
并发多个线程在一个单核cpu上进行资源抢占并运行就是并发。 多线程在cpu中是并发运行的下面会详细解释并发还有和并行的区别 首先我们要知道在cpu这里指的是单核cpu中在某一个时间片只能有一个线程在cpu中运行。一个cpu在同一时间只能执行一个线程。
为什么使用并发
在一个进程中有多个线程需要执行这些线程会抢占cpu的时间片来运行自身。有人会问为什么不等一个线程执行完之后再去执行另一个线程呢思考一下我们在使用电脑的时候可以同时看文档听音乐。如果cpu设计成一个线程执行完之后再去执行另一个线程你就只能听完音乐在去看文档在听音乐的过程中你的鼠标都移动不了鼠标也是一个单独线程你们觉得这样的体验好吗所以cpu肯定不能这样设计。
并发的执行原理
操作系统是以抢占式的方法来调度线程的也有其他方法我们目前先学这一种。就是线程自己去强cpu的资源谁先抢到谁就在cpu上运行一个时间片这个时间片很短很短。这里的线程会有优先级的特点优先级高的线程抢到cpu的概率大概率大概率大是概率大不代表一定能抢到运行完成之后释放cpu资源回去重新抢占cpu。因为运行的时间很短所以在人为感官上觉得这些线程始再同时运行的。 其实上面多个线程抢占cpu资源就是多线程的并发。
注意这里是一个cpu。随着需求的不断增高科技的不断发展单核cpu的性能已经不能满足效率。于是就出现了多核cpu也就出现了并行
并行
并行在同一时间点多个线程同时运行在多核cpu的多个核上这叫并行。和并发不同的是同一时间在并行中线程可以同时运行而并发则只能有一个线程运行。
线程的五种状态
创建状态
当用new操作符创建一个线程时 例如new Thread®线程还没有开始运行此时线程处在新建状态。 当一个线程处于新生状态时程序还没有开始运行线程中的代码
就绪状态
一个新创建的线程并不自动开始运行要执行线程必须调用线程的start()方法。当线程对象调用start()方法即启动了线程start()方法创建线程运行的系统资源并调度线程运行run()方法。当start()方法返回后线程就处于就绪状态。 处于就绪状态的线程并不一定立即运行run()方法线程还必须同其他线程竞争CPU时间只有获得CPU时间才可以运行线程。因为在单CPU的计算机系统中不可能同时运行多个线程一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的。
运行状态
当线程获得CPU时间后它才进入运行状态真正开始执行run()方法.
阻塞状态
线程运行过程中可能由于各种原因进入阻塞状态: 1线程通过调用sleep方法进入睡眠状态 2线程调用一个在I/O上被阻塞的操作即该操作在输入输出操作完成之前不会返回到它的调用者 3线程试图得到一个锁而该锁正被其他线程持有 4线程在等待某个触发条件
死亡状态
有两个原因会导致线程死亡 1 run方法正常退出而自然死亡 2 一个未捕获的异常终止了run方法而使线程猝死。 为了确定线程在当前是否存活着就是要么是可运行的要么是被阻塞了需要使用isAlive方法。如果是可运行或被阻塞这个方法返回true 如果线程仍旧是new状态且不是可运行的 或者线程死亡了则返回false.
如图所示
线程的创建方式
继承Thread 实现Runnable 匿名内部类方式 上面只要会继承THread类方法和实现Runnable接口这两种就行还有其他的线程池创建等等在后面的章节说
迷惑问题
继承THread类方法和实现Runnable接口 这两种方式选择哪一种好呢
在java语言中有一个特点就是单继承多实现。实现了接口还可以继续继承继承了类不能再继承。所以一般情况下使用实现Runnable会有更好的拓展性。
继器启动线程是调用run方法还是start方法
Run方法仅仅只是线程所要执行的代码块部分如果调用run方法就和调用其他普通方法一样从上到下顺序执行。没有了多线程的特点。所以使用start方法使线程进入就绪状态。
线程的分类
用户线程也叫前台线程
用户自定义创建的线程用户线程的状态不受其他线程的影响。别的线程挂了就挂了影响不到他因为他们是互相独立的。
守护线程也叫后台线程
守护线程受用户线程的影响当用户线程销毁后守护线程也会跟着销毁。比如GC
分享一波:程序员赚外快-必看的巅峰干货