并发


1、并发的基础

  • 线程的基本概念

    • 表示一条单独的执行流,有自己的程序执行计数器,自己的栈
    • 两种创建方式:继承Thread;实现Runnable接口
    • 无论哪种创建方式最后都需要调用start方法启动线程
  • synchronized

    • 可用于修饰类的实例方法、静态方法和代码块
    • 多个线程可以同时执行同一个synchronized实例方法,只要访问的对象不同即可,synchronized实例方法实际保护的是同一个对象的方法调用,确保同时只能有一个线程执行
    • 可重入性
    • 内存可见性
  • 线程基本协作机制

    • wait/notify方法只能在synchronized代码块内调用
  • 线程的中断

    • 中断不是强迫终止一个线程,而是一种协作机制,给线程传递一个取消信号,但是由线程决定如何以及何时推出

2、并发包的基石

  • 原子变量和CAS

  • CAS:compareAndSet,比较并设置,有两个参数expect和update,以原子的方式实现:如果当前值等于expect则更新为update,否则不更新,如果更新成功返回true否则返回false

  • 原子变量的更新逻辑是非阻塞式的,更新冲突的时候j就重试,不会阻塞,不会有上下文切换开销。synchronized代表一种阻塞式算法,得不到锁的时候进入锁等待队列,等待其他线程唤醒,有上下文切换开销。

  • 显式锁

  • 可重入锁ReentrantLock

1、可重入
2、解决竞态条件问题
3、保证内存可见性

  • yield只是告诉操作系统可以让其他线程运行,但自己依然式可运行状态,而park会放弃调度资格,使线程进入WAITING状态

  • AQS:可以保存锁当前持有线程,提供方法进行查询和设置,内部维护了一个等待队列,借助CAS实现无阻塞算法进行更新

  • 显式条件

3、并发容器

  • CopyOnWriteArrayList

  • 线程安全,可以被多个线程并发访问

  • 迭代器不支持修改

  • 内部是个数组,以原子方式被整体更新

  • 读不需要锁,可以并行,多个线程不能同时写,每个写操作都需要先获取锁,内部使用ReentrantLock

  • CopyOnWriteArraySet:内部通过CopyOnWriteArrayList实现

  • ConcurrentHashMap

  • 弱一致性:迭代器创建后,会按照哈希表结构遍历每个元素,遍历过程中内部元素如果在已遍历过的部分发生变化,迭代器就不会反映出来,如果在未遍历过的部分发生变化则迭代器就会发现并反映出来

  • 并发版的HashMap,通过降低锁的粒度和CAS等实现高并发,支持原子条件更新

  • 不会抛出ConcurrentModificationException,实现弱一致性

  • 锁的粒度:锁住多大的范围

  • 并发队列

  • 无锁非阻塞并发队列:ConcurrentLinkedQueue和ConcurrentLinkedDeque

  • 普通阻塞队列:基于数组的ArrayBlockingQueue,基于链表的LinkedBlockingQueue和LinkedBlockingDeque

  • 优先级阻塞队列:PriorityBlockingQueue

  • 延时阻塞队列:DelayQueue

  • 其他阻塞队列:SynchronousQueue和LinkedTransferQueue

SynchronousQueue适用于两个线程之间直接传递信息、事件或任务

4、异步任务执行服务

  • 基本概念和原理

  • Runnable接口没有返回结果,Callable有;Runnable不会抛出异常,而Callable会

  • 线程池

  • 两个概念:任务队列;工作者线程

工作者线程主体是一个循环不断从队列中接受任务并执行,任务队列保存待执行的任务

  • 优点

1、重用线程,避免线程创建的开销
2、任务过多时通过排队避免创建过多线程,减少系统资源消耗和竞争

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值