想要解决死锁的问题,首先我们要明确死锁的原因
1.互斥使用
即线程1使用了锁A,线程2也想使用锁A,那么这个时候线程2就使用不了锁A
2.不可抢占
即当前线程需要使用锁A,需要等待上一个使用锁A的线程将锁释放,才可以使用锁A,不可抢占执行
3.请求和保持
即线程1拿到锁A之后,不想释放,还想要拿到锁B
4.循环等待
线程1等待线程2释放锁B,线程2等待线程3释放锁C,线程3等待线程1释放锁A
以上是我们多线程死锁的必要条件,只要有一个不满足,那么死锁就解决了
问题123都不是我们可以控制的,所以只能从循环等待下手
只要我们约定好加锁的顺序,那么循环等待就可以被打破
我们拿哲学家进餐问题来举个例子
如下图,有五位哲学家,在一起吃饭,如果其中一个想要吃到面,需要拿到左右手的叉子才可以吃,吃完了会把叉子放下来,这样当这个叉子用完之后,别的哲学家才可以使用那个叉子
我们会发现,当我们五个哲学家都先拿左手的叉子的时候,那么这时候,就会产生死锁,从而导致五个哲学家都无法进餐
我们的解决方案是给每一个叉子编号,从1-5,如果哲学家想要吃面,那么需要先拿编号较小的那个,才可以拿另一个,这样就有效的解决了死锁问题
学校操作系统课程中给出的方案是银行家算法,这种方案虽然也可以解决死锁问题,但是不太适合实际开发,而我们的方案是比较简单,容易实现的
这里面的解决方案就是改变加锁的顺序,在实际开发中,遇到多把锁,一定得多长心眼,否则很可能出现死锁问题,改变加锁的顺序,基本可以处理掉%95的死锁问题,以后我们就可以在处理死锁的问题上,优先考虑能否通过改变加锁的顺序,来解决死锁问题