并发三要素:

可见性:一个线程对共享变量的修改,另一个线程能马上看到(CPU缓存引起)

原子性:一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。(CPU线程分时复用引起)

有序性:即程序执行的顺序按照代码的先后顺序执行

 

可见性:volatile

原子性:java中只有简单的读取、赋值(而且必须是将数字赋值给某个变量,变量之间的相互赋值不是原子操作)才是原子操作。

有序性:sychronized lock

 

happer-before原则:

单一线程原则

管程锁定规则

volatile变量规则

线程启动规则

线程加入规则

线程中断规则

对象终结规则

传递性

一个类在可以被多个线程安全调用时就是线程安全的,

不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。

 

不可变对象一定是线程安全的:final关键字修饰的基本数据类型;String;枚举类型;Number部分子类

绝对线程安全:调用者不需要额外的同步措施

相对线程安全:相对线程安全需要保证对这个对象单独的操作是线程安全的,在调用的时候不需要做额外的保障措施。但是对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性(Vector、HashTable、Collections 的 synchronizedCollection() 方法包装的集合等。)

线程兼容

线程兼容是指对象本身并不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全地使用,我们平常说一个类不是线程安全的,绝大多数时候指的是这一种情况。Java API 中大部分的类都是属于线程兼容的,如与前面的 Vector 和 HashTable 相对应的集合类 ArrayList 和 HashMap 等。

线程对立:通常有害

 

线程安全的实现方法:

互斥同步:synchronized 和 ReentrantLock。

非阻塞同步:CAS,AtomicInteger,ABA

无同步方案:栈封闭(虚拟机栈上的局部变量),线程本地存储(

ThreadLocal 从理论上讲并不是用来解决多线程并发问题的,因为根本不存在多线程竞争。

在一些场景 (尤其是使用线程池) 下,由于 ThreadLocal.ThreadLocalMap 的底层数据结构导致 ThreadLocal 有内存泄漏的情况,应该尽可能在每次使用 ThreadLocal 后手动调用 remove(),以避免出现 ThreadLocal 经典的内存泄漏甚至是造成自身业务混乱的风险。),可重入代码

 

  • 多线程的出现是要解决什么问题的?
  • 线程不安全是指什么? 举例说明
  • 并发出现线程不安全的本质什么? 可见性,原子性和有序性。
  • Java是怎么解决并发问题的? 3个关键字,JMM和8个Happens-Before
  • 线程安全是不是非真即假? 不是
  • 线程安全有哪些实现思路?
  • 如何理解并发和并行的区别?

JAVA中的锁:

乐观锁 悲观锁(宏观概念)

自旋锁 自适应自旋锁

无锁 偏向锁 轻量级锁 重量级锁

公平锁 非公平锁

可重入锁 非可重入锁

独享锁(排他锁) 共享锁

 

 

posted on 2023-03-20 15:34  JohnWangzx  阅读(17)  评论(0编辑  收藏  举报