小吃店网站建设,广告公司上班有前景吗,沈阳手机网站,网站开发实战网络课目录
一. 什么是线程安全
二. 线程安全问题产生的原因
三. 线程安全问题的解决
3.1 解决修改操作不是原子性的问题 加锁
a. 什么是锁
b. 没有加锁时
c. 加锁时
d. 死锁
e. 避免死锁
3.2 解决内存可见性的问题 volatile关键字 (易变的, 善变的)
a. 不加…目录
一. 什么是线程安全
二. 线程安全问题产生的原因
三. 线程安全问题的解决
3.1 解决修改操作不是原子性的问题 加锁
a. 什么是锁
b. 没有加锁时
c. 加锁时
d. 死锁
e. 避免死锁
3.2 解决内存可见性的问题 volatile关键字 (易变的, 善变的)
a. 不加volatile关键字
b. 加volatile关键字 一. 什么是线程安全
在多线程并发执行的过程中, 出现 bug, 称为线程不安全. 反之则线程安全. 二. 线程安全问题产生的原因
1. 操作系统对于线程的调度是随机的, 抢占式的[根本原因].
2. 多个线程修改同一个变量.
3. 修改操作不是原子的. 解决: 锁
4. 内存可见性. 解决: volatile(adj. 善变的. 易变的)关键字
5. 执行重排序. 解决: wait() 与 notify() 等待 与 通知 三. 线程安全问题的解决
3.1 解决修改操作不是原子性的问题 加锁
a. 什么是锁 synchronized修饰普通方法, 是对this加锁.
synchronized修饰静态方法, 是对类对象加锁.
b. 没有加锁时 没有对count操作进行加锁时, count的结果总是 100000, 这是因为(线程调度是随机的, 抢占式的 count操作不是原子的) c. 加锁时 对count操作进行加锁后, count操作可以认为变成原子的了, 这时, count的最终结果就符合预期. d. 死锁 构成死锁的场景: 1. 一个线程, 一把锁 (但是, java中锁具有可重入特性, 此种情况下, 并不会构成死锁) 2. 两个线程, 两把锁 3. n个线程, m把锁 构成死锁的四个必要条件: 1. 锁是互斥的. (线程1获取了锁1, 这时线程2想要再获取锁1 就要阻塞等待) 2. 锁是不可抢占的 3. 请求和保持. (线程1获取了锁1, 线程2获取了锁2, 此时, 线程1想要再获取锁2, 线程2想要再获取锁1, 这时就会构成死锁, 线程阻塞) 解决: 一定情况下, 避免嵌套 4. 循环等待. 解决: 约定加锁的顺序. e. 避免死锁 想要避免死锁, 就要解决 3 或者 4 这两个必要条件. 解决3. (避免嵌套) 解决4.(按照一定的顺序进行加锁) 3.2 解决内存可见性的问题 volatile关键字 (易变的, 善变的)
a. 不加volatile关键字 可以观察到, t1线程并没有因为t2线程输入val的值不是0而结束, 反而一直在RUNNABLE(运行中). 这是因为, jvm对代码进行了优化, jvm检测到val的值一直不发生改变, 为了提高效率, 就把val转移到了寄存器中, 此时t2线程输入val还在和内存进行交互, 并不会改变val的值. b. 加volatile关键字 加上volatile关键字, 表示val的值是易变的, 用户随时可能会修改, 此时, jvm就不会对val的操作进行优化, val一直存在于内存中. 未完成...