并发编程

本文深入解析并发、并行与串行的区别,探讨线程与进程的管理,详解上下文切换的影响,多线程问题及解决方案,包括死锁条件、线程池使用、AQS框架原理等,是理解并发编程不可或缺的指南。

并发、并行与串行

  1. 并发:单核多任务,按时间片轮流交替执行
  2. 并行:多核多任务,同时进行
  3. 串行:多个任务按顺序进行

线程与进程

进程是资源分配的基本单位,线程任务调度与执行的基本单位
线程又被称为轻量级进程,同一进程中的线程共享进程的资源,线程之间切换的开销要远小于进程之间的切换

什么是上下文切换

cpu采用的是为每个线程分配时间片并轮转的形式,当千任务在执行完cpu时间片会切换到另一任务前会保存自己的状态,以便下次切换回这个任务可以加载这个任务状态。任务从保存到再加载的过程就是一次上下文切换,计算密集型,可能是
操作系统中消耗最大的操作。

多线程的问题

  • 线程多,占用内存高
  • 线程管理需要CPU时间跟踪
  • 线程之间对共享资源的访问会相互影响,因此要解决竞争共享资源的问题

查找cpu利用率高的线程

  1. top: 找到利用率最高的进程的pid
  2. top -H -p pid:找出进程中利用率最高的线程、
  3. 转16进制
  4. jstack pid > /tem t.dat:打印进程信息
  5. 查看该日志文件
线程死锁的条件
互斥
请求保持
不可剥夺
循环等待
创建线程的方法
  1. 继承Thread类,重写run方法
  2. 实现runnable接口,重写run,作为参数传递给Thread类
  3. 实现callable方法,重写call,作为参数传给FutureTask,再传给Thread,可以获得返回值
  4. 线程池:全部实现ExectuorService接口
    在这里插入图片描述
    其中Executors工具类提供了一系列方法用于创建线程池
    newFixedThreadPool,newSingleThreadExecutor-------容易任务堆积出现溢出
    newCachedThreadPool,newScheduledThreadPool-------线程过多出现溢出

FutureTask
在这里插入图片描述
运算没结束get方法会一直阻塞

线程生命周期

wait/notify/notifyAll

必须在同步块中调用,wait会释放锁notify要获取锁,他们是object的方法,因为任何一个对象都可以获取多个锁

线程池流程
  1. 无界队列:一直添加
  2. 有界队列:

    1. Abort:抛出异常
    2. Discard:直接丢弃
    3. DiscardOldest:丢弃最老的
    4. callerrun:由调用线程去处理
Happends-before
  1. volatile的写操作发生在读操作前
  2. 线程启动先于该线程的其他操作
  3. 线程内按顺序
  4. unlock发生在lock前
  5. interrupt一定发生在线程的中断前
  6. 线程内任何操作都先于检测到该线程结束
  7. 构造先于finalizer前
  8. 传递性

AQS

一个用来构建锁和同步器的框架
核心思想:
请求的资源空闲,则将请求该资源的线程置为有效线程并将资源锁定,若是被占用,则将其加入等待队列,AQS使用CLH(虚拟双向队列,将线程封装成一个节点并维持节点之间的关系)来实现锁分配

AQS使用一个volatile修饰的共享变量表示同步状态
资源的共享方式:

  1. 独占:只允许一个线程执行
    1. 公平锁:按顺序
    2. 非公平锁:抢占式
  2. 共享:countdownLatch、cyclicBarrier…

线程池
建议ThreadPoolExecutor来自己手动编写
1. core
2. max
3. queue
4. keepAlive
5. 单位
6. ThreadFactory
7. 拒绝策略

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值