【Java多线程】概述

来源:互联网 发布:知乎注册在哪里 编辑:程序博客网 时间:2024/05/21 09:37

线程与进程的异同

1.定义

  • 进程:操作系统可以同时执行多个任务,每个任务就是进程;

  • 线程:进程的执行单元,也是进程内的可调度实体。

2.线程与进程的关系

  一个程序运行后至少有一个进程,一个进程可以拥有多个线程,但至少要包含一个 线程(主线程,即Java中的main()方法执行后的线程)。一个线程必须有一个父进程,线程的调度和管理由进程本身完成。

3.线程与进程的区别

  • 地址空间:进程内的一个执行单元,进程至少有一个线程;它们共享进程的地址空间(也有少量自己的地址空间),而进程有自己独立的地址空间(多个进程之间一般不会共享地址空间);

  • 资源拥有:进程是资源拥有的单位,同一个进程内的线程共享进程的资源;

  • 线程是处理器调度和分派的基本单位;

  • 进程为重量级组件,线程为轻量级组件;

  • 二者均可并发执行.多线程程序的并发性高。

  • 进程的切换代价远高于线程,同步和通信的实现也比线程复杂。

  • 多进程是指在操作系统中能同时运行多个任务(程序),多线程是指在同一应用程序中有多个功能流同时执行

4.适用场景

  进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,需要用多线程,例如:

①、利用它可以完成重复性的工作(如实现动画、声音等的播放)。

②、从事一次性较费时的初始化工作(如网络连接、声音数据文件的加载)。

③、并发执行的运行效果(一个进程多个线程)以实现更复杂的功能

为什么要使用多线程

1.引入

JDK 5.0 提供了JUC包(java.util.concurrent ),在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的Collection 实现等。

JUC图解

这里写图片描述

2.程序运行的更快

  • 由于线程比进程更轻量级、所以它们比进程更容易创建,也容易撤销。同时因为多个线程共享父进程里的全部资源,因此编程更加方便。

  • 若多个线程都是CPU密集型(进程占用CPU时间较长)的,那么并不能获得性能上的增强,但是如果存在着大量的计算和大量的I/O处理,即I/O密集型的,那么拥有多个线程允许这些活动彼此重叠进行,从而会加快应用程序执行的速度。

3.比多进程更方便

进程之间不能共享内存,但线程之间共享内存非常容易,系统创建进程时需要为该进程重新分配系统资源,但创建线程则代价小得多,因此使用多线程来实现多任务并发比多进程的效率高。

使用多线程的好处

1.并行操作,可以减轻系统性能方面的瓶颈;

2.提高CPU的处理器的效率,在多线程中,通过优先级管理,可以使重要的程序优先操作,提高了任务管理的灵活性;还可以把不同的线程在不同的CPU中执行,真正做到同时处理多任务。

使用多线程带来的挑战

如果你希望通过多线程执行任务让程序运行的更快,会面临非常多的挑战,比如上下
文切换的问题,死锁的问题,以及受限于硬件和软件的资源限制问题。

怎么解决这些挑战呢?

例如:如何减少上下文切换

解决方法:

①无锁并发编程,将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。

②CAS算法。Java的Atomic包用CAS(Compare And Set)算法更新数据而不需要加锁。

③使用最少线程。

④.协程(Coroutine):在单线程里实现多任务的调度,并在单线程立维持多个任务间的切
换。

注:采用Coroutine方式可以很好的绕开需要启动太多线程来支撑高并发出现的瓶颈,提高Java应用所能支撑的并发量,但在开发模式上也会带来变化,并且需要特别注意不能造成线程被阻塞的现象,



本人才疏学浅,若有错误,还请指出
谢谢!

原创粉丝点击