并发编程

 

 

 

Synchronized和ReentrantLock 的区别

 

 

线程让出CPU的情况

Java并发,说一说了解哪些,volatie个synchronized的区别

(1)volatile本质是告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取。synchronized

则是锁定当前变量,只有当前线程可以访问该变量,其它线程被阻塞。

(2)volatile仅能使用在变量级别,synchronized则可以使用在变量、方法。

(3)volatile仅能实现变量修改的可见性,而synchronized则可以保证变量修改的可见性和原子性

定义long或double  时,如果使用volatile关键字(简单的赋值与返回操作),就会获得原子性。

(常规状态下,这两个变量由于其长度,其操作不是原子的)

(4)volatile不会造成线程阻塞,synchronized造成线程阻塞

使用volatile而不是synchronized的唯一安全情况是类中只有一个可变的域。

BLOCKED 和 WAIT的区别

线程的状态

 

 

中断机制,isInterrupted和interrupted的区别,哪些状态可以中断并抛出InterruptedException

(1)intertrupte()在阻塞状态抛出异常,再补货后修改变量。

(2)isinterrupted用来判断状态。

   线程的Interrupt()中断,其实只是修改线程的中断位,并不会真正停止线程。

(1)可以通过Thread的类方法interrupted检查当前线程是否中断,但是会重置标志位

(2)通过调用Thread的普通方法isInterrupted来检查中断位,不会重置标志位。

讲一讲并行和并发

两个进程之间哪些东西是独立的

线程同步的方式

一、不可变  二、互斥同步 三、非阻塞同步(CAS2. AtomicInteger。ABA)

四、无同步方案(栈封闭,线程本地存储,可重入代码

可重入锁怎么实现 SY锁和Lock锁

不可重入会导致死锁,都是通过计数器加一来实现,

如何判断当前线程是否持有锁

后来我发现线程(Thread)有一个名为holdsLock(Object obj)的静态方法,它根据线程是

否对传递的对象持有锁来返回true或false。

单核单线程CPU是否可以运行多线程程序?多线程与CPU单线程区别(系统线程和用户线程)?

什么是线程不安全

是指不提供加锁机制保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

CAS和Sychronized

简单的来说 CAS 适用于写比较少的情况下(多读场景,冲突一般较少),
synchronized 适用于写比较多的情况下(多写场景,冲突一般较多)

(1)CAS 只能保证一个共享变量的原子操作

(2)循环时间长开销大

(3) ABA 问题
(4)CAS 基于硬件实现,不需要进入内核,不需要切换线程,操作自旋几率较少,

       因此可以获得更高的性能 

Sychronized引入的 偏向锁 轻量级以及其它各种优化 synchronized 底层

实现主要依靠Lock-Free的队列,基本思路是 自旋后阻塞竞争切换后继续竞争锁

稍微牺牲了公平性,但得了高吞吐量。在线程冲突较少的情况下,可以获得和 CAS

类似的性能;而线程冲突严重的情况下,性能远高于CAS 

非公平锁

当线程A执行完之后,要唤醒线程B是需要时间的,而且线程B醒来后还要再次竞争锁,

所以如果在切换过程当中,来了一个线程C,那么线程C是有可能获取到锁的

获取多选的锁,“锁“具体是什么,如何确定对象的锁”

“ 锁 ” 的 本 质 其 实 是 monitorenter 和 monitorexit 字 节 码 指 令 的 一个 Reference 类 型

的 参 数 , 即 要 锁 定 和 解 锁 的 对 象 。 当 一 个 对 象 被 锁 住 时 , 对 象 里 面 所 有

用 Synchronized 修 饰 的方 法 都 将 产 生 堵 塞而 对 象 里 非 Synchronized 修 饰 的

方 法 可 正 常 被调 用 , 不 受 锁 影 响

 跟 Synchronized 相 比 , 可 重 入 锁 ReentrantLock 其 实 现原 理 有 什 么 不 同 ?

其 实 , 锁 的 实 现 原 理 基 本 是 为 了 达 到 一 个 目 的 :让 所 有 的 线 程 都 能 看 到 某

种 标 记 。Synchronized 通 过 在 对 象 头 中 设 置 标 记 实 现 了 这 一 目 的 , 是 一 种 JVM

原 生 的 锁 实 现 方 式 ,而 ReentrantLock 以 及 所 有 的 基 于 Lock 接 口 的实 现 类 , 都 是

通 过 用 一 个 volitile 修 饰 的 int 型 变 量 ,并 保 证 每 个 线程 都 能 拥 有 对 该 int 的 可 见 性

和 原 子 修 改 , 其 本 质 是 基 于 所 谓 的 AQS框 架 。

问 题 二 : 那 么 请 谈 谈 AQS 框 架 是 怎 么 回 事 儿

AQS( AbstractQueuedSynchronizer 类 ) 是 一 个 用 来 构 建 锁 和 同 步 器的 框 架 , 各 种

Lock 包 中 的 锁 ( 常 用 的 有 ReentrantLock、ReadWriteLock) , 以 及 其 他 如 Semaphore、

CountDownLatch, 甚至 是 早 期 的 FutureTask 等 , 都 是 基 于 AQS 来 构 建 。

1. AQS 在 内 部 定 义 了 一 个 volatile int state 变 量 , 表 示 同 步 状 态 : 当 线程 调 用 lock 方 法 时 ,

如 果 state=0, 说 明 没 有 任 何 线 程 占 有 共 享 资 的 锁 , 可 以 获 得 锁 并 将 state=1; 如 果 state=1,

则 说 明 有 线 程 目 前 正 在使 用 共 享 变 量 , 其 他 线 程 必 须 加 入 同 步 队 列 进 行 等 待 。

2. AQS 通 过 Node 内 部 类 构 成 的 一 个 双 向 链 表 结 构 的 同 步 队 列 , 来 完 成 线

程 获 取 锁 的 排 队 工 作 , 当 有 线 程 获 取 锁 失 败 后 , 就 被 添 加 到 队 列 末 尾
 Node 类 是 对 要 访 问 同 步 代 码 的 线 程 的 封 装 , 包 含 了 线 程 本 身 及 其 状 态 叫
waitStatus( 有 五 种 不 同 取 值 , 分 别 表 示 是 否 被 阻 塞 , 是 否 等 待 唤 醒 否 已 经 被 取 消 等 ) ,

每 个 Node 结 点 关 联 其 prev 结 点 和 next 结
点 , 方 便 线 程 释 放 锁 后 快 速 唤 醒 下 一 个 在 等 待 的 线 程 , 是 一 个 FIFO 的 过
程 。
 Node 类 有 两 个 常 量 , SHARED 和 EXCLUSIVE, 分 别 代 表 共 享 模 式 和 独
占 模 式 。 所 谓 共 享 模 式 是 一 个 锁 允 许 多 条 线 程 同 时 操 作 ( 信 号 量
Semaphore 就 是 基 于 AQS 的 共 享 模 式 实 现 的 ) , 独 占 模 式 是 同 一 个 时
间 段 只 能 有 一 个 线 程 对 共 享 资 源 进 行 操 作 , 多 余 的 请 求 线 程 需 要 排 队 等 待
( 如 ReentranLock) 。
3. AQS 通 过 内 部 类 ConditionObject 构 建 等 待 队 列 ( 可 有 多 个 ) , 当
Condition 调 用 wait() 方 法 后 , 线 程 将 会 加 入 等 待 队 列 中 , 而 当
Condition 调 用 signal() 方 法 后 , 线 程 将 从 等 待 队 列 转 移 动 同 步 队 列 中
进 行 锁 竞 争 。
4. AQS 和 Condition 各 自 维 护 了 不 同 的 队 列 , 在 使 用 LockCondition 的 时 候 ,

实 就 是 两 个 队 列 的 互 相 移 动 。

 ReentrantLock 是 如 何 实 现 可 重 入 性 的
ReentrantLock 内 部 自 定 义 了 同 步 器 Sync( Sync 既 实 现 了 AQS,
又 实 现 了 AOS, 而 AOS 提 供 了 一 种 互 斥 锁 持 有 的 方 式 ) , 其 实 就 是
加 锁 的 时 候 通 过 CAS 算 法 , 将 线 程 对 象 放 到 一 个 双 向 链 表 中 , 每 次 获
取 锁 的 时 候 , 看 下 当 前 维 护 的 那 个 线 程 ID 和 当 前 请 求 的 线 程 ID 是 否
一 样 , 一 样 就 可 重 入 了 。

 

 

CopyOnWriteArrayList
什 么 是 Java 的 内 存 模 型 

 

Java 的 内 存 模 型 定 义 了 程 序 中 各 个 变 量 的 访 问 规 则 , 即 在 虚 拟 机 中 将变 量 存 储

到 内 存 和 从 内 存 中 取 出 这 样 的 底 层 细 节 。此 处 的 变 量 包 括 实 例 字 段 、静 态 字 段

和 构 成 数 组 对 象 的 元 素 , 但 是 不 包括 局 部 变 量 和 方 法 参 数 , 因 为这 些 是 线 程 私

有 的 , 不 会 被 共 享 , 所 以 不存 在 竞 争 问 题 。

请 谈 谈 ThreadLocal 是 怎 么 解 决 并 发 安 全 的 ?

ThreadLocal 这 是 Java 提 供 的 一 种 保 存 线 程 私 有 信 息 的 机 制 , 因 为其 在 整 个 线 程

生 命 周 期 内 有 效 , 所 以 可 以 方 便 地 在 一 个 线 程 关 联 的 不 同业 务 模 块 之 间 传 递

信 息 , 比 如 事 务 ID、 Cookie 等 上 下 文 相 关 信 息 。ThreadLocal 为 每 一 个 线 程 维 护

变 量 的 副 本 , 把 共 享 数 据 的 可 见 范 围 限制 在 同 一 个 线 程 之 内 , 其 实 现 原 理 是 ,

在 ThreadLocal 类 中 有 一 个Map, 用 于 存 储 每 一 个 线 程 的 变 量 的 副 本 。

很 多 人 都说 要 慎 用 ThreadLocal, 谈 谈 你 的 理 解 , 使 用ThreadLocal 需 要 注 意 些 什 么 ?

使 用 ThreadLocal 要 注 意 remove!ThreadLocal 的 实 现 是 基 于 一 个 所 谓 的 ThreadLocalMap,

ThreadLocalMap 中 , 它 的 key 是 一 个 弱 引 用 。通 常 弱 引 用 都 会 和 引 用 队 列 配 合 清 理

机 制 使 用 , 但 是 ThreadLocal 是个 例 外 , 它 并 没 有 这 么 做 。这 意 味 着 , 废 弃 项 目 的

回 收 依 赖 于 显 式 地 触 发 , 否 则 就 要 等 待 线 程 结束 , 进 而 回 收 相 应 ThreadLocalMap!

这 就 是 很 多 OOM 的 来 源 , 所以 通 常 都 会 建 议 , 应 用 一 定 要 自 己 负 责 remove, 并 且

不 要 和 线 程 池 配合 , 因 为 worker 线 程 往 往 是 不 会 退 出 的 。 

 线程池参数

 

线程池拒绝策略

 

 线程池类型

线程池线程数怎么设置?

 

 

 

 

 

 

 

 

 




 

posted on 2020-04-01 00:39  huangzhihao  阅读(208)  评论(0)    收藏  举报