Spinlock:什么是自旋锁
在进一步了解自旋锁之前,先来理解下自旋锁的概念。什么是自旋锁?自旋锁有那些用途?和另一种互斥锁又是什么怎么回事儿?
首先来看一种需要锁控制访问的情况,比如两个线程要更新某个值给内存中的某个变量。如果按照互斥锁的方法就是线程1获得锁,更新变量,这时如果线程2想要获取锁就会进入wait状态,CPU此时就会发生线程切换,执行其他线程的任务。问题是线程1需要占用锁的时间很短,很快啊,啪的一下...(对不起,被马老师的视频洗脑了)很快线程1就释放了锁,那么线程2就需要经过线程切换才能让CPU继续执行代码。这显然是不够高效的,加大了开销。有没有什么好的办法避免这个问题呢?
有,解决问题的点在于线程获取锁的时候如果没有获取锁,不会直接进入wait状态,而是进入一个获取锁的循环,直到获取锁之后再退出循环。这样CPU就会一直执行代码,不会因为线程2处于wait状态而发生线程切换,降低开销。这就会是自旋锁。
那自旋锁这么好为什么还要互斥锁呢?这是因为如果上面那个例子中不是更新内存中的变量而是更新大量数据到本地文件这种非常耗时的操作,需要占用较长时间,这时再用自旋锁就会使CPU长时间执行线程2的循环检查锁代码,其他线程得不到执行而产生线程饥饿Thread Starvation
。所以自旋锁适合那些锁占用很短的任务减少线程切换开销,而占用时间较长的任务适合使用互斥锁提高CPU线程执行数防止线程饥饿。总结在下面的表格中:

对于不知道是什么样类型的任务,采取什么类型的锁好呢?自旋锁+互斥锁。首先是用自旋锁获取一定的次数,如果在该次数内仍未获得锁就使用互斥锁进入wait状态。这样可以平衡自旋锁和互斥锁的优点。
AtomicInteger
中通过CAS(compare and swap)方法来保证线程安全,本质也是自旋锁的应用。这里仅对自旋锁的概念做简单介绍,暂时不能提供自旋锁更多深入的理解。