主线:互斥锁 —> 死锁 —> 乐观锁与悲观锁 —> 数据库中的锁(并发插入如何避免重复插入)
一、线程同步、异步、互斥
1、线程同步:
是指多个线程通过特定的设置(如互斥量、事件对象、临界区)来控制线程之间的执行顺序。这里的同步不是同时进行。
也就是说,线程之间通过同步建立起执行顺序的关系,如果没有同步,那线程之间是各自运行各自的!
进一步的说明:就是前一个进程的输出作为后一个进程的输入,当第一个进程没有输出时第二个进程必须等待。具有同步关系的一组并发进程相互发送的信息称为消息或事件。
其中并发又有伪并发和真并发,伪并发是指单核处理器的并发,真并发是指多核处理器的并发。
2、线程异步:
异步和同步是相对的,同步就是顺序执行,执行完一个再执行下一个,需要等待、协调运行。异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。
线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其它的事情。异步和多线程并不是一个同等关系,异步是最终目的,
多线程只是我们实现异步的一种手段。异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事情。实现异步可以采用多线程技术或则交给另外的进程来处理。
3、线程互斥:
是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。
线程互斥可以看成是一种特殊的线程同步。
4、多线程的三个特性:
原子性、可见性、有序性
5、如何保证线程同步?
java笔记–关于线程同步(7种同步方式): https://www.cnblogs.com/XHJT/p/3897440.html
<MFC笔记> 四种线程同步(或互斥)方式小结:https://blog.csdn.net/ebowtang/article/details/29905309
二、死锁
1、定义
两个或两个以上的线程均持有对方不会释放的资源,在相互请求这些不释放的资源而处于一种永久的等待状态。
一句话描述:多个并发线程因争夺(互斥)资源而产生相互等待的现象。
2、典型的两种死锁的情形:
(1)线程自己锁住自己:
一般情况下,如果一个线程先后调用两次lock(),由于锁已经被占用,该线程会一直挂起等待占有锁的线程释放锁,然而锁正是被自己占用,该线程又被挂起而没机会释放锁。因此,就永远处于挂起状态了,于是就形成了死锁。
(2)多线程抢夺资源被困
线程1锁住了A,接着尝试对B进行加锁,同时线程2已经锁住了B,又尝试着对A加锁。为了得到彼此的资源A和B,线程1和线程2将永远的阻塞下去,这样就发生了死锁。
3、死锁的产生四个必要条件:
互斥条件:资源不能被共享,具有排它性,即一个资源只能被一个线程占用,直到被改线程释放。
请求与保持条件:一个进程因请求被占用资源而发生阻塞时,对已获得的资源保持不放。
非剥夺条件:任何一个资源在没被该进程释放之前,任何其他进程都无法对他剥夺占用。
循环等待条件:系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。
4、引起死锁的原因、如何避免死锁?
https://blog.csdn.net/yangqiang387393/article/details/52155259
参考:
https://blog.csdn.net/ebowtang/article/details/29905309
https://blog.csdn.net/cqkxboy168/article/details/9026205/
https://blog.csdn.net/ebowtang/article/details/29905309