进程和线程区别,死锁,内存泄露和内存溢出,线程安全和不安全,四种线程池

进程和线程区别,死锁,内存泄露和内存溢出,线程安全和不安全,四种线程池

1.线程和进程的区别

  • 进程
    进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。
    进程一般由程序,数据集合和进程控制块三部分组成。
进程具有的特征:
1.动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
2.并发性:任何进程都可以同其他进行一起并发执行;
3.独立性:进程是系统进行资源分配和调度的一个独立单位;
4.结构性:进程由程序,数据和进程控制块三部分组成 ;
  • 线程
    线程是进程当中的一条执行流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。
    一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID,当前指令指针PC,寄存器和堆栈组成。而进程由内存空间(代码,数据,进程空间,打开的文件)和一个或多个线程组成。
  • 进程和线程的区别
    线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元;而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都有若干个线程,至少包含一个线程。
  • 根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位(也可以理解为进程当中的一条执行流程)
    • 资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
    • 包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
    • 内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的。
    • 影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
    • 执行过程:每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行。
    • 调度和切换:线程上下文切换比进程上下文切换要快得多。
  • 多进程和多线程区别
    多进程:操作系统中同时运行的多个程序
    多线程:在同一个进程中同时运行的多个任务
    多线程并不能提高运行速度,但可以提高运行效率,让CPU的使用率更高。但是如果多线程有安全问题或出现频繁的上下文切换时,运算速度可能反而更低。

2.什么是死锁,产生死锁的原因及必要条件

死锁==,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。
死锁产生的原因

  • 竞争资源
  • 进程间推进顺序非法

产生死锁的必要条件
1.互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
2.请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
3.不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
4.环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链。

解决死锁的办法

预防死锁:

  1. 资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
  2. 只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
  3. 可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
  4. 资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)

1.以确定的顺序获得锁(比如银行家算法)
2.超时放弃

避免死锁
银行家算法:每一个新进程进入系统时,必须声明需要每种资源的最大数目,其数目不能超过系统所拥有的的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程,若有,再进一步计算在将这些资源分配给进程后,是否会使系统处于不安全状态如果不会才将资源分配给它,否则让进程等待。

检测死锁
1.首先为每个进程和每个资源指定一个唯一的号码;
2.然后建立资源分配表和进程等待表。

解除死锁
当发现有进程死锁后,便应立即把它从死锁状态中解脱出来,常采用的方法有:

  • 剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;
  • 撤消进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。
    原文链接:https://blog.csdn.net/hd12370/article/details/82814348

3.堆和栈的区别

1、堆栈空间分配区别
栈(操作系统):由操作系统(编译器)自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式类似于链表。

2、堆栈缓存方式区别
栈使用的是一级缓存, 它们通常都是被调用时处于存储空间中,调用完毕立即释放。
堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
3、堆栈数据结构区别
堆(数据结构):堆可以被看成是一棵树,如:堆排序。先进先出的结构。
栈(数据结构):一种先进后出的数据结构。

堆和栈的区别
堆和栈的区别主要有五大点,分别是:
1、申请方式的不同。栈由系统自动分配,而堆是人为申请开辟;
2、申请大小的不同。栈获得的空间较小,而堆获得的空间较大;
3、申请效率的不同。栈由系统自动分配,速度较快,而堆一般速度比较慢;
4、存储内容的不同。栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部用一个字节存放堆的大小,堆中的具体内容是人为安排;
5、底层不同。栈是连续的空间,而堆是不连续的空间。

4.内存泄露和内存溢出

内存泄露(Memory Leak):是指程序在申请内存后,无法释放已申请的内存空间(程序中有引用没有释放,不能被GC回收)。一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是会导致内存溢出。
内存溢出(Out Of Memory):它是指程序在申请内存时,没有足够的内存空间供其使用,抛出OutOfMemory异常。
比如申请了一个8MB空间,但是当前内存可用空间只有5MB,那么就是内存溢出。
二者的关系和区别
关系
1.内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。
就相
当于你租了个带钥匙的柜子,你存完东西之后把柜子锁上之后,把钥匙丢了或者没有将钥匙还回去,那么结果就是这个柜子将无法供给任何人使用,也无法被垃圾回收器回收,因为找不到他的任何信息。

2.内存泄漏的堆积最终会导致内存溢出,由于系统中的内存是有限的,如果过度占用资源而不及时释放,最后会导致内存不足,从而无法给所需要存储的数据提供足够的内存,从而导致内存溢出。

3.导致内存溢出也可能是由于在给数据分配大小时没有根据实际要求分配,即请求的内存空间超过了系统实际分配给你的内存空间,最后导致分配的内存无法满足数据的需求,从而导致内存溢出。
区别:
内存泄露是由于GC无法及时或者无法识别可以回收的数据进行及时的回收,导致内存的浪费;内存溢出是由于数据所需要的内存无法得到满足,导致数据无法正常存储到内存中。内存泄露的多次表现就是会导致内存溢出。
内存溢出的解决方法
第一步,修改JVM启动参数,直接增加内存(-Xms,-Xmx参数一定不要忘记加);
第二步,检查错误日志,查看“OutOfMemory”错误前是否有其 它异常或错误;
第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

5.多进程和多线程的使用场景

多进程模型的优势是CPU,多线程模型的优势是线程间切换代价较小
1、多进程应用场景
nginx主流的工作模式是多进程模式(也支持多线程模型)
几乎所有的web server服务器服务都有多进程的,至少有一个守护进程配合一个worker进程,例如apached,httpd等等以d结尾的进程包括init.d本身就是0级总进程,所有你认知的进程都是它的子进程;
chrome浏览器也是多进程方式
(原因:①可能存在一些网页不符合编程规范,容易崩溃,采用多进程一个网页崩溃不会影响其他网页;而采用多线程会。②网页之间互相隔离,保证安全,不必担心某个网页中的恶意代码会取得存放在其他网页中的敏感信息。)
redis也可以归类到“多进程单线程”模型(平时工作是单个进程,涉及到耗时操作如持久化或aof重写时会用到多个进程)
2、多线程应用场景
线程间有数据共享,并且数据是需要修改的(不同任务间需要大量共享数据或频繁通信时)。
提供非均质的服务(有优先级任务处理)事件响应有优先级。
单任务并行计算,在非CPU Bound的场景下提高响应速度,降低时延。
与人有IO交互的应用,良好的用户体验(键盘鼠标的输入,立刻响应)
案例:
桌面软件,响应用户输入的是一个线程,后台程序处理是另外的线程;

原文链接:https://blog.csdn.net/abcdefg12345666/article/details/111739157

6.线程安全和线程不安全

线程安全:指的是多个线程在执行同一段代码时采用加锁机制,使每次的执行结果和单线程执行的结果是一样的,不存在执行线程时出现意外结果。
线程不安全:是指不提供加速机制保护,有可能出现多个线程先后出现更改数据造成得到的数据是脏数据。

可能导致并发问题的原因:

  • 中断:假如有一段代码正在执行,如果发生一个中断(中断随机发生),代码重新排队等待下一次调度。下一次调度重新运行当前代码时,共享内存可能被其他线程修改过了。
  • 睡眠:假如有一段代码正在执行,如果源码sleep了,代码重新排队等待下一次调度。下一次调度重新运行当前代码时,共享内存可能被其他线程修改过了。
  • 同步:假如有一段代码正在正在执行,如果源码中想要获取一个互斥锁,但是这个锁已经被占用了,这时候代码就会重新排队等待下一次调度。下一次调度重新当前代码段时的共享内存可能被其他线程修改过了。
  • 对称多处理:多个CPU可以同时执行一段代码。
  • 抢占式内核:内核中的任务可能被另一个任务抢占,下一次调度当前代码段时共享内存可能被其他线程修改过。

7.常见4种线程池

FixedThreadPool
特点:

  • 核心线程数==最大线程数
  • 阻塞队列是无界的,可以放任意数量的任务
  • 适用于任务量已知,相对耗时的任务

CachedThreadPool
特点:

  • 核心线程数为0,最大线程数为Integer.MAX_VALUE,救急线程的空闲时间为60s,意味着:
    全部都是救急线程
    救急线程可以无限创建

  • 队列采用SynchronousQueue实现特点是,它没有容量,没有线程来取是放不进去的(一手交钱,一手交货)

  • 整个线程线程数会根据任务量不断增长,没有上限,任务执行完毕,60s后释放线程

  • 适合任务数比较密集,但每个任务执行时间较短的情况

ScheduledThreadPool
定长线程池:
特点:

  • 支持定时和周期性任务执行

SingleThreadExecutor
特点:

  • 线程数始终为1,不能修改。希望多个任务排队执行。任务数多于1时,会放入无界队列排队。任务执行完毕后,唯一的进程也不会被释放。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值