多线程知识扫盲

 

一,进程,多线程基础预览

A, 进程:
  • 1.进程是一个具有一定独立功能的程序关于某次数据集合的一次运行活动,它是操作系统分配资源的基本单元.

  • 2.进程是指在系统中正在运行的一个应用程序,就是一段程序的执行过程,我们可以理解为手机上的一个app.

  • 3.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内,拥有独立运行所需的全部资源

B, 线程
  • 1.程序执行流的最小单元,线程是进程中的一个实体.

  • 2.一个进程要想执行任务,必须至少有一条线程.应用程序启动的时候,系统会默认开启一条线程,也就是主线程

C, 进程和线程的关系
  • 1.线程是进程的执行单元,进程的所有任务都在线程中执行

  • 2.进程是操作系统进行资源分配的最小单位,线程是操作系统调度的最小单位,即CPU分配时间的单位。

3.一个程序可以对应多个进程(多进程),一个进程中可有多个线程,但至少要有一条线程

  • 4.同一个进程内的线程共享进程资源

5,二者的生命周期基本一致:新建,就绪,运行,阻塞,死亡

 

D、多进程

打开Windows任务管理器

  • 进程可以分为系统进程和用户进程。凡是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身;所有由用户启动的进程都是用户进程。进程是操作系统进行资源分配的单位。

  • 进程又被细化为线程,也就是一个进程下有多个能独立运行的更小的单位。在同一个时间里,同一个计算机系统中如果允许两个或两个以上的进程处于运行状态,这便是多进程。

 

E、 多线程

  • 1.同一时间,CPU只能处理1条线程,只有1条线程在执行。多线程并发执行,其实是CPU快速地在多条线程之间调度(切换)。如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象

  • 2.如果线程非常非常多,CPU会在N多线程之间调度,消耗大量的CPU资源,每条线程被调度执行的频次会降低(线程的执行效率降低)

3.多线程的优点:

能适当提高程序的执行效率

  • 能适当提高资源利用率(CPU、内存利用率)

4.多线程的缺点:

开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能

线程越多,CPU在调度线程上的开销就越大

  • 程序设计更加复杂:比如线程之间的通信、多线程的数据共享

 

F、并行、并发、高并发等概念
  • 并行:多个CPU实例或多台机器同时执行一段处理逻辑,是真正的同时。

  • 并发:通过CPU调度算法,让用户看上去同时执行,实际上CPU操作层面不是真正的同时。并发时如果操作了公用资源,可能产生线程安全问题。

  • 高并发:高并发指的是是一种系统运行过程中遇到的一种“短时间内遇到大量操作请求”的情况,主要发生在web系统集中大量访问或者socket端口集中性收到大量请求(例如:12306的抢票,春晚抢红包)。

 

F、多线程与高并发的联系
  • 多线程只是在同/异步角度上解决高并发问题的其中的一个方法手段,是在同一时刻利用计算机闲置资源的一种方式。

  • 多线程在高并发问题中的作用就是充分利用计算机资源,使计算机的资源在每一时刻都能达到最大的利用率,不至于浪费计算机资源使其闲置。

二,Java中线程及多线程

A,JVM线程生命周期

线程是 JVM 执行任务的最小单元,理解线程的状态转换是理解后续多线程问题的基础。在 JVM 运行中,线程一共有 NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED 六种状态,这些状态对应 Thread.State 枚举类中的状态。

如下图所示,当创建一个线程时,线程处在 NEW 状态,运行 Thread 的 start 方法后,线程进入 RUNNABLE 可运行状态。

 

B,使用线程池创建多线程,实现异步调用

线程池通过复用线程,避免线程频繁地创建和销毁。Java 的 Executors 工具类中提供了 5 种类型的线程池创建方法,如下图所示,来看它们的特点和适用场景。

C,应对多线程并发问题所使用的锁

1,单机场景下的synchronized,锁对象&方法->对象;锁类和静态方法->类的所有对象

2,分布式场景下的分布式锁,一般使用Redis控制即可。比如封装好的工具类,Redisson。

 

D,Java中的并发容器

1,ConcurrentHashMap,读写并发。较HashMap,其在并发性上读不锁,写的时候锁粒度减小为segment而不是整张表,也就意味着一定程度上可以进行“并发写”。

2,CopyOnWriteArrayList,实现读写分离。读的时候不加锁不阻塞,iterator自诞生之时起就指着一个原版读,由于写是在副本上写,所以读不会出问题。

 

 

 

原文地址:https://www.cnblogs.com/Jashinck/p/15114998.html