
什么是死锁?
死锁是一种情况,其中多个线程同时被阻塞,并且其中一个或所有线程都在等待释放资源. 由于线程被无限期阻塞,因此程序无法正常运行. 从视觉上讲,这是: 一件宝藏需要打开两个钥匙,并且两个人同时进入. 他们每个人都有一把钥匙,但是双方都等着对方交出钥匙来打开宝藏. 没有人释放自己的钥匙. 这样,两个人就陷入僵局,直到开发人员发现这种情况为止.
死锁的根本原因是不正确地使用了“ synchronized”关键字来管理对特定对象的线程访问. “ synchronized”关键字的作用是确保一次块仅允许一个线程执行特定代码,因此,被允许执行的线程必须首先具有对该变量或对象的独占访问权限. 当线程访问该对象时,该线程将锁定该对象,并且此锁将导致要访问同一对象的其他线程被阻塞,直到第一个线程释放它放置在该对象上的锁为止.

如果您对同步了解不多,请单击此处
例如
大多数死锁发生在您不知道的时候. 让我们举个例子看看什么是僵局.

1. 同步嵌套.
The
synchronized关键字可以确保当多个线程访问synced方法时确保同步. 即,当线程A访问此方法时,线程B也访问此方法. 这时,线程B将阻塞. 等待线程A执行,然后才能访问它. 在这里线程死锁,我们将使用由sync持有的同步锁. 有关详细信息,请查看代码:

//首先我们先定义两个final的对象锁.可以看做是共有的资源.
final Object lockA = new Object();
final Object lockB = new Object();
//生产者A
class ProductThreadA implements Runnable{
@Override
public void run() {
//这里一定要让线程睡一会儿来模拟处理数据 ,要不然的话死锁的现象不会那么的明显.这里就是同步语句块里面,首先获得对象锁lockA,然后执行一些代码,随后我们需要对象锁lockB去执行另外一些代码.
synchronized (lockA){
//这里一个log日志
Log.e("CHAO","ThreadA lock lockA");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB){
//这里一个log日志
Log.e("CHAO","ThreadA lock lockB");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//生产者B
class ProductThreadB implements Runnable{
//我们生产的顺序真好好生产者A相反,我们首先需要对象锁lockB,然后需要对象锁lockA.
@Override
public void run() {
synchronized (lockB){
//这里一个log日志
Log.e("CHAO","ThreadB lock lockB");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockA){
//这里一个log日志
Log.e("CHAO","ThreadB lock lockA");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//这里运行线程
ProductThreadA productThreadA = new ProductThreadA();
ProductThreadB productThreadB = new ProductThreadB();
Thread threadA = new Thread(productThreadA);
Thread threadB = new Thread(productThreadB);
threadA.start();
threadB.start();
分析,当线程A开始执行run方法时,它将首先保持对象锁localA线程死锁,然后休眠2秒钟. 这时,threadB也开始执行run方法,该方法持有localB对象锁. 当threadA运行时找到第二种同步方法时,无法使用localB的对象锁(threadB没有释放localB锁),threadA在这里停止以等待localB锁. 然后线程B还执行第二种同步方法以访问localA对象锁. 发现还没有释放localA(线程A没有释放localA锁),并且threadB也在这里停止以等待localA锁被释放. 这样,两个线程都无法继续执行并进入死锁状态. 查看结果: p>
10-20 14:54:39.940 18162-18178/? E/CHAO: ThreadA lock lockA 10-20 14:54:39.940 18162-18179/? E/CHAO: ThreadB lock lockB
当没有死锁时,应该打印四个日志,并且在这里明显出现死锁现象.

死锁的原因
当我们了解发生死锁的情况以及什么是死锁时,我们应该在编写代码时尝试避免这种误解. 死锁必须同时满足以下四个条件,只要其中之一满足任何条件,就不会发生死锁.
解决方案陷入僵局
说实话,为避免死锁,编写自己的代码时必须注意. 这里是对其他人的解决方案的参考,但是我对这些解决方案并不了解,它们太模糊并且没有具体示例.
以上是本文的全部内容. 希望对大家的学习有所帮助. 我也希望每个人都支持该脚本主页.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-146221-1.html
满屏的水军