原子操作:多线程程序中“最小的且不可并行化的”操作
比较并交换:(CAS原子操作,分两步,比较,交换;单纯CAS不行,还得锁总线操作,防止一个线程比较交换中切换线程)多个线程操作同一变量,记录变量修改前的值,修改后比较修改前的值是否一致,一致就更新为修改后的值,不一致就不更新为修改后的值
流水线:(CPU)一个指令执行时,切换执行顺序将相同的电路单元放在一起执行,这样不同电路单元切换的次数会少很多,执行效率高
处理器如何实现原子操作?
1.使用总线锁保证原子性
2.使用缓存锁保证原子性
有两种情况下处理器不会使用缓存锁定?
1.当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行(cache line)时,则处理器会调用总线锁定。
2.有些处理器不支持缓存锁定。对于Intel 486和Pentium处理器,就算锁定的内存区域在处理器的缓存行中也会调用总线锁定。
不加锁CAS比较并交换也能保证线程安全,适合低并发高并发会一直CPU自旋浪费,重量级锁用CAS不会CPU的无限自旋更新浪费,一旦更新失败会进入阻塞队列不再CAS,从而减少CPU的浪费
Java如何实现原子操作?
1.使用锁机制实现原子操作
2.使用循环CAS实现原子操作
CAS实现原子操作的三大问题?
1.ABA问题:(版本号代替初值来判断原值是否改变)初值由A换成B又换成A,线程没有感知到初值变化而更新值
2.循环时间长开销大,CPU不断的CAS自旋操作更新值,更新失败再读取更新
3.只能保证一个共享变量的原子操作,CAS只能保证一个共享变量的原子操作,多个共享变量的原子操作要靠代码等其他方式实现
用户线程:平时用到的普通线程均是用户线程,当在Java程序中创建一个线程,它就被称为用户线程;不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统中也可实现,但线程的调度需要用户程序完成,这有些类似 Windows 3.x 的协作式多任务。
守护线程:是个服务线程,准确地来说就是服务其他的线程,这是它的作用——而其他的线程只有一种,那就是用户线程。所以java里线程分2种,1、守护线程,比如垃圾回收线程,就是最典型的守护线程。2、用户线程,就是应用程序里的自定义线程
重入锁:重入锁ReentrantLock,顾名思义,就是支持重进入的锁,他表示该锁能够支持一个线程对资源的重复加锁。除此之外,该锁还支持获取锁时的公平和非公平选择。
重入锁的作用:为了避免死锁。是对非可重入锁的增强,避免非可重入锁在嵌套使用时产生死锁。