Java/Android 进程与线程之 多线程基础(一)

1、线程

1.1定义

一个基本的CPU执行单元 & 程序执行流的最小单元,比进程更小的可独立运行的基本单位,可理解为:轻量级进程
组成:线程ID + 程序计数器 + 寄存器集合 + 堆栈
注:线程自己不拥有系统资源,与其他线程共享进程所拥有的全部资源。

1.2作用

减少程序在并发执行时所付出的时空开销,提高操作系统的并发性能。

1.3 状态及状态转换

在这里插入图片描述

1.4分类

1.41 守护线程

守护用户线程的线程,即在程序运行时为其他线程提供一种通用服务,如垃圾回收线程

1.42 非守护线程

a.主线程(UI线程)
Android系统在程序启动时会自动启动一条主线程,用于处理四大组件与用户进行交互的事情(如UI、界面交互相关)
注:因为用户随时会与界面发生交互,因此主线程任何时候都必须保持很高的响应速度,所以主线程不允许进行耗时操作,否则会出现ANR
b.子线程(工作线程)
用户手动创建的线程,用于处理耗时的操作(网络请求、I/O操作等)
c.守护线程 & 非守护线程的区别
区别:虚拟机是否已退出:
当所有用户线程结束时,因为没有守护的必要,所以守护线程也会终止,虚拟机也同样退出;反过来,只要任何用户线程还在运行,守护线程就不会终止,虚拟机就不会退出。守护线程不属于不可或缺的存在。

1.5 优先级

线程优先级分为10个级别,分别用Thread类常量表示。

Thread.MIN_PRIORITY // 优先级1
Thread.MAX_PRIORITY // 优先级10

通过方法 setPriority(int grade) 进行优先级设置
默认线程优先级是5,即 Thread.NORM_PRIORITY,数字越高,优先级越高

2、进程

2.1 定义

是进程实体的运行过程 & 系统进行资源分配和调度的一个独立单位

2.2 状态

在这里插入图片描述

线程与进程区别

在这里插入图片描述

3、多线程

3.1 定义

一个程序(进程)运行时产生多个线程(任务)同时进行

3.2 多线程目的

提高CPU资源的利用率,包括以下三点:

  • 避免阻塞(异步调用)
    单个线程中的程序,是顺序执行的。如果前面的操作发生了阻塞,那么就会影响到后面的操作。
  • 避免CPU空转
    如果服务器只用单线程,即处理完一条HTTP请求,再处理下一条请求的话,CPU会存在大量的闲置时间。因为处理一条请求,经常涉及到RPC、数据库访问、磁盘IO等操作,这些操作的速度比CPU慢很多,而在等待这些响应的时候,CPU却不能去处理新的请求,其余的请求只能一直处于等待状态,因此服务器的性能就很差
  • 提升性能
    多线程可以同时执行多个任务,对于可并发执行的任务而言,确实提高了性能。

3.3 并行与并发

并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
并发:单位时间内运行的线程数,离开时间量度就没有意义。通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。其实,多线程本质是并发执行程序。因为计算机任何特定时刻只能执行一个任务;多线程只是一种错觉:只是因为JVM快速调度资源来轮换线程,使得线程不断轮流执行,所以看起来好像在同时执行多个任务而已(异步执行)

3.4 同步与异步

同步:发送一个请求,等待返回,然后再发送下一个请求;同步可以避免出现死锁,读脏数据的发生,可以保证安全性。
异步:发送一个请求,不等待返回,随时可以再发送下一个请求;异步则是可以提高效率,可以并发执行多项工作。

3.5 线程安全

一段代码是线程安全的是指:在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。
线程不安全就意味着线程的调度顺序会影响最终结果,则程序执行的结果并不是我们想要的结果,甚至有可能会导致实际场景严重的安全问题。

3.6 多线程开发原则

1、不要阻塞UI线程(即主线程):单线程会导致主线程阻塞,然后出现ANR错误:主线程被阻塞超过5s则会出现错误,(将耗时任务放在工作线程中执行)
2、不要在UI线程之外更新UI组件 (将更新UI组件放在主线程中执行)

3.7 线程调度

3.7.1调度方式

1、当系统存在大量线程时,系统会通过时间片轮转的方式调度线程,因此线程不可能做到绝对的并发
2、处于就绪状态(Runnable)的线程都会进入到线程队列中等待CPU资源(同一时刻在线程队列中可能有很多个)
3、在采用时间片的系统中,每个线程都有机会获得CPU的资源以便进行自身的线程操作;当线程使用CPU资源的时间到后,即时线程没有完成自己的全部操作,JVM也会中断当前线程的执行,把CPU资源的使用权切换给下一个队列中等待的线程。(被中断的线程将等待CPU资源的下一次轮回,然后从中断处继续执行)

3.7.2调度优先级

Java虚拟机(JVM)中的线程调度器负责管理线程,并根据以下规则进行调度:
1、根据线程优先级(高-低),将CPU资源分配给各线程
2、具备相同优先级的线程以轮流的方式获取CPU资源

3.7.3 产生死锁条件

  • 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。
  • 占有和等待:已经得到了某个资源的进程可以再请求新的资源。
  • 不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
  • 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。

3.7.4死锁的处理方法

  • 鸵鸟策略
    当发生死锁时不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略(忽略它)
  • 死锁的检测与死锁恢复
    检测:从一个节点出发进行深度优先搜索,对访问过的节点进行标记,如果访问了已经标记的节点,就表示有向图存在环,也就是检测到死锁的发生
  • 死锁的预防
    (1)破坏互斥条件
    例如假脱机打印机技术允许若干个进程同时输出,唯一真正请求物理打印机的进程是打印机守护进程。
    (2)破坏占有和等待条件
    一种实现方式是规定所有进程在开始执行前请求所需要的全部资源。
    (3)破坏不可抢占条件
    (4)破坏环路等待
    给资源统一编号,进程只能按编号顺序来请求资源。
  • 死锁的避免
    算法要做的是判断对请求的满足是否会进入不安全状态,如果是,就拒绝请求;否则予以分配

面试题总结

1、线程?进程?线程与进程的区别

2、线程优先级设置

3、多线程目的,并行与并发区别

4、死锁怎么产生的,怎么避免死锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值