多线程(一)——多线程简介和线程的生命周期

多线程的简介

串行与并发

如果在程序中,有多个任务需要被处理,此时的处理方式可以有串行并发

  • 串行(同步):所有的任务,按照一定的先后顺序,依次执行。如果前面的任务没有执行结束,后面的任务等待。
  • 并发(异步):多个任务可以同时执行。在一个时间段之内,可以同时处理多个任务。

生活中,其实有很多串行和并发的案例。最常见的就是排队买饭。小明到KFC吃饭,发现有好几个窗口可以点餐。小明选择了其中的一个窗口进行排队。此时,KFC采用的模式就是串行加并发的模式。每一个窗口前,都有很多顾客在排队,此时他们之间就是串行的任务,前面的顾客没有处理完,后面所有的顾客只能等待。同时,多个窗口之间的顾客是可以同时点餐的,这就是并发的任务。

使用并发任务,也可以在一定程度上提高效率。例如:KFC中有100个人点餐,每一个人点餐需要1分钟。如果只有一个窗口可以点餐,那么需要花费100分钟;如果有两个窗口可以点餐,那么需要花费50分钟;如果有十个窗口可以点餐,那么需要花费10分钟。因此,使用并发,可以在一定程度上提高程序的执行效率,缩短执行的时间。

在程序中,有些操作是比较耗时的,特别是涉及到非常大的文件的处理、或者网络文件的处理。此时就需要使用异步任务来处理,否则就会阻塞主线程,导致用户交互的卡顿。合适的使用并发任务,可以在一定程度上提高程序的执行效率。

并发的原理

一个程序如果需要被执行,必须的资源是CPU和内存。在内存上开辟空间,为程序中的变量进行数据的存储;同时需要CPU处理程序中的逻辑。现在处于一个硬件过剩的时代,但是即便是硬件不发达的时代,并发任务也是可以实现的。以单核的CPU为例,处理任务的核心只有一个,那就意味着,如果CPU在处理一个程序中的任务, 其他所有的程序都得暂停。那么并发是怎么实现的呢?

其实所谓的并发,并不是真正意义上的多个任务同时执行。而是CPU快速的在不同的任务之间进行切换。在某一个时间点处理任务A,下一个时间点去处理任务B,每一个任务都没有立即处理结束。CPU快速的在不同的任务之间进行切换,只是这个切换的速度非常快,人类是识别不了的,因此会给人一种“多个任务在同时执行”的假象。

因此,所谓的并发,其实就是CPU快速的在不同的任务之间进行切换的一种假象。

思考:
既然多个任务并发,可以在一定程度上提高程序的执行效率,那么并发数量是不是越高越好呢?
并不是!多个任务的并发,其实就是CPU在不同的任务之间进行切换。如果并发的数量过多,会导致分配到每一个任务上的CPU时间片较短,也并不见得会提高程序的执行效率。而且,每一个任务的载体(线程)也是需要消耗资源的,过多的线程,会导致其他资源的浪费。

例如:小明雇保姆干活,那么是不是保姆越多越好呢?
不一定!雇保姆需要花钱,就类比于开辟线程执行并发的任务需要消耗资源一样。那么在雇保姆的时候就得想,你真的需要这么多保姆吗?家里有十件事情需要处理, 那么就一定需要雇十个保姆吗?没有必要!

进程和线程

  • 进程:对一个程序在运行过程中,占用的各种资源的描述。
  • 线程: 是进程中的一个执行单元。其实在操作系统中,最小的任务执行单元并不是线程,是句柄。但是句柄过小,操作起来非常麻烦,因此,在Java中我们可以认为线程就是任务的最小执行单元。
    其实,对于操作系统来说,一个任务就是一个进程。例如:打开了QQ,那么QQ就是一个进程;再打开一个QQ,此时会开辟一个新的QQ进程;打开了一个微信,就开辟了一个微信进程。在一个任务中,有的时候是需要同时处理多件事情的,例如打开了一个QQ音乐,需要同时播放声音和歌词。那么这些进程中的子任务,就是一个个的线程。

多个线程的同时执行,是需要这些线程去争抢CPU资源,而CPU资源的分配是以时间片位单位的。例如,某一个线程抢到了0.01秒的CPU时间片,在这个时间段内, CPU会处理这个线程中的任务。至于哪一个线程能够抢到CPU时间片,由操作系统进行统一的资源调度。

进程和线程的异同

  • 相同点:进程和线程都是为了处理多个并发任务而存在的。
  • 不同点:进程之间是资源不共享的,一个进程中不能访问另外的进程中的数据。而线程之间是资源共享的,一个进程中的多个线程可以共享同一个数据。也正因为线程之间是资源共享的,所以会出现临界资源问题。

进程和线程的关系

一个进程,在开辟的时候,会自动的创建一个线程,来处理这个进程中的任务,这个线程被称为是主线程。在程序运行的过程中,还可以开辟其他的线程。这些被开辟出来的线程,都是子线程。

也就是说,一个进程中,是可以包含多个线程的。一个进程中的某一个线程崩溃了,只要还有其他线程存在,就不会影响整个进程的执行。但是如果一个进程中,所有的线程都执行结束了,那么这个进程也就终止了。

线程的生命周期

线程的状态

线程的生命周期,指的是一个线程对象,从最开始的创建,到最后的销毁,中间所经历的过程。在这个过程中,线程处于不同的状态:

  • New:新生态,一个线程对象被实例化完成的时候,就处于这个状态。
  • Runnable:就绪态,处于这个状态的线程,可以参与CPU时间片的争抢。
  • Run:运行态,某一个线程抢到了CPU时间片,可以执行这个线程中的逻辑。
  • Block:阻塞态,线程由于种种原因,暂时挂起,处于阻塞(暂停)状态。 个状态的线程,不参与CPU时间片的争抢。
  • Dead:死亡态,线程即将被销毁。

线程的生命周期图

总结

进程:正在进行中的程序也就是在内存中开辟的一块空间
线程:负责程序执行的一条执行路径也称为一个执行单元进程的执行实际上是线程在执行一个进程至少包括一个线程如果一个进程包括多个线程,那么就是多线程程序了。多线程实现了同时执行的效果,多个线程在互相争抢cpu,谁抢到谁执行,直到线程把自己的代码全部执行完,线程结束。

  • 线程的功能不同,则线程执行的代码写的位置就不同
  • main方法中写的代码是主线程负责执行的
  • 垃圾回收线程执行的代码在finalize方法中

猜你喜欢

转载自www.cnblogs.com/dch-21/p/12803685.html