1.互斥锁:
互斥锁是一种「独占锁」,比如当线程 A 加锁成功后,此时互斥锁已经被线程 A 独占了,A可以共享系统资源。只要线程 A 没有释放手中的锁,线程 B 加锁就会失败,加锁失败后,内核会将线程置位睡眠状态,等到A线程释放,内核会在合适的时机唤醒线程。B线程就拿到锁可以访问系统资源。
2.自旋锁:
自旋锁在【用户态】完成加速和解锁操作,所以相比互斥锁来说,开销小,速度快。自旋锁会查看锁的状态,如果锁是空闲的。将锁设置为前进程持有。如果锁住的代码执行时间很短,而应该选用自旋锁。访问cpu资源。
3.读写锁:
如果只读取共享资源用「读锁」加锁,如果要修改共享资源则用「写锁」加锁。当「写锁」没有被线程持有时,多个线程能够并发地持有读锁,这大大提高了共享资源的访问效率,一旦「写锁」被线程持有后,读线程的获取读锁的操作会被阻塞,而且其他写线程的获取写锁的操作也会被阻塞。
4.优先锁:(读锁高并发,写锁会阻塞。解决读写锁出现的阻塞问题)
用队列把获取锁的线程排队,不管是写线程还是读线程都按照先进先出的原则加锁即可,
这样读线程仍然可以并发,也不会出现「饥饿」的现象。
5.乐观锁:
先修改完共享资源,再验证这段时间内有没有发生冲突,如果没有其他线程在修改资源,那么操作完成,如果发现有其他线程已经修改过这个资源,就放弃本次操作。只有在冲突概率非常低,且加锁成本非常高的场景时,才考虑使用乐观锁。
6.悲观锁:
互斥锁、自旋锁、读写锁,都是属于悲观锁,悲观锁做事比较悲观,它认为多线程同时修改共享资源的概率比较高,于是很容易出现冲突,所以访问共享资源前,先要上锁.
7.线程的上下文切换的是什么?
当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。