多线程的出现是要解决什么问题
- 为了合理利用cpu的高性能
并发出现问题的三大要素
- cpu高速缓存引起的可见性(一个线程对共享变量的修改,另外一个线程能够立刻看到。)
- 分时复用引起的原子性(经典银行转账问题)
- 重排序引起的有序性
java如何解决高并发问题的
-
JMM(java内存模型)规范了JVM如何提供按序禁用缓存和编译优化的方法
-
volatile、sychronized和final三个关键字的使用
-
使用synchronized和Lock来保证线程的原子性
-
通过synchronized和Lock也能够保证可见性,synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中。因此可以保证可见性。
-
可以通过volatile关键字解决有序性, JMM则是通过Happens-Before规则保证有序性
单一锁定原则:在一个线程内,程序前面的操作先行与后面的操作 管程锁定原则:一个unlock操作先行发生于后面对同一个锁的lock操作 volatile变量原则:一个volatile变量的写操作先发生于对这个变量的读操作 线程加入规则:Thread对象的结束先行join()方法返回 线程中断规则:线程的interrupt方法的调用先行发生于线程正常的中断事件,可用于检测 是否有中断事件
线程安全是不是非真既假 (不是)
对于不同的变量有着不同的线程安全级别
- 不可变
- 对于任何不可变得变量在不同的线程中引用都不会出现线程安全,所以现在多线程环境下尽量使对象成为不可变对象,来满足线程安全
- 绝对线程安全(不管环境如何,调用者都不需要任何额外的同步措施)
- 相对线程安全
- 这需要保证对这个对象的单独操作是线程安全的,在调用时不需要做额外的保障措施,但是对于一些顺序的连续调用,可能需要在调用端做一些额外的同步操作
- 例如Vector、HashTable、Collections 的 synchronizedCollection() 方法包装的集合等
- 线程兼容
- 线程兼容是指,一些类本身不是线程安全的,但是可以通过一些同步手段使之安全的被使用,在java中绝大部分api指的就是这种情况
- 线程对立(就是调用端是否采用了同步措施,都无法在多线程环境中使用的代码——有害的)
线程安全有哪些实现思路
- 互斥同步(阻塞同步)
- synchronized
- ReentrantLock
- 非阻塞同步(乐观锁)
- CAS(基于硬件的同步方式,三个操作数,内存地址V,预期值A,新值B,执行操作时V等于A,才将V的值更新为B)冲突检测
- 每条线程都直接先去执行操作,计算完成后检测是否与其他线程存在共享数据竞争,如果没有则让此操作成功,如果存在共享数据竞争则可能不断地重新执行操作和检测,直到成功为止,可叫CAS自旋
- CAS
- 无同步方案
- 线程本地存储(Thread Local storage)ThreadLocal详解
- 可重入代码
如何理解并发和并行的区别
并发:
并行:描述具有处理多个