并发编程系列之基础篇(一)—多线程基本概念

Java多线程系列之基础篇(一)—多线程基本概念

前言

大家好,牧码心从此系列开始将给大家推荐java多线程方面内容,今天给大家推荐一篇Java多线程系列之基础篇(一)—基本概念的文章,希望对你有所帮助。内容如下:

  • 多线程概念
  • 进程和线程
  • 线程的状态
  • 几个关键字
  • 多线程的注意点

概要

随着现代操作系统发展,多处理器的诞生,若系统同一时刻只处理一个任务,效率会变得很低,并且不能充分发挥计算机的能力,达到充分利用计算机资源的效果。所以为了更好的利用系统资源,提高任务执行效率,多线程的使用就应运而生。同时也会涉及到多线程,多进程,并发,并行等概念,这里我们先阐述下它们的含义。

  • 多进程:指操作系统同时运行多个程序,如你在电脑上中同时运行着QQ、IE、微信等程序。
  • 多线程:指在同一个进程中同时运行多个线程,如你开启QQ聊天,可以开启多个窗口。
  • 并发:指多个任务在同一时间段内发生,任务有可能交替执行,也有可能串行执行。形象的说两个人交替使用同一台计算机。
  • 并行:指多个任务在同一时刻在多个CPU上同时发生。形象的说两个人同时使用同两台计算机。

进程和线程

进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,由相关堆栈(系统栈或用户栈)寄存器和线程控制表TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其他线程的相关变量。
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度,从而显著提高系统资源的利用率和吞吐量。
总的来说,线程与进程的区别可以归纳为以下几点:

  • 地址空间和资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
  • 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信,需要进程同步和互斥手段的辅助,以保证数据的一致性。
  • 调度和切换:线程上下文切换比进程上下文切换要快得多。

线程的状态

通常创建一个线程有继承Thread类和实现Runnable的方式(具体详见Java多线程系列之基础篇(二)—实现多线程的几种方式),创建完的线程具有生命周期,从创建到死亡,中间还有一些其他状态的变化,下图是线程运行过程中状态流程图:
线程运行过程中状态流程图
从图中我们可以看到线程有以下几个状态:

  1. 新建状态(New) : 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。
  2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。
  3. 运行状态(Running) : 线程获取CPU资源后进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
  4. 阻塞状态(Blocked) : 阻塞状态是线程因为某种原因让出CPU资源,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
    (01) 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成。
    (02) 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
    (03) 其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  5. 死亡状态(Dead) : 线程顺利执行完了或者因异常退出了run()方法,该线程结束生命周期。

几个关键字

  • Object类:定义了wait(), notify(), notifyAll()等休眠/唤醒函数。
  • Thread类:定义了一些列的线程操作函数。例如,sleep()休眠函数, interrupt()中断函数, getName()获取线程名称等。
  • synchronized:它区分为synchronized代码块和synchronized方法。synchronized的作用是让线程获取对象的同步锁

多线程注意点

多线程编程给我们带来了很多的优势,如充分利用处理器资源,并行做多件事情,但是在开发多线程应用时,我们需要注意的问题有很多,比如线程同步、线程死锁等等。

  • 线程安全
    在单线程环境下,不加锁也没有线程安全和不安全问题,但多线程访问时,需要线程同步访问来保证线程安全,如同时有两个线程,线程A和线程B,对同一个账号金额进行修改操作,当采用了加锁机制时,A线程在修改账号金额,B线程不能进行访问,直到A线程读取完,B线程才可使用,这样就不会出现数据不一致或者数据污染。

  • 线程死锁
    线程死锁是指多个线程竞争同一个资源,各自阻塞等待其他线程持有的锁,例如:
    1.线程1锁住了A资源,然后尝试去对B资源加锁,同时线程2已经锁住了B资源,再尝试对A加锁,为了彼此都能得到所需的资源而相互阻塞等待,从而产生了死锁。

参考

  • https://www.cnblogs.com/skywang12345/p/3479024.html
发布了91 篇原创文章 · 获赞 27 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/xhwwc110/article/details/105491229