本文详细介绍了Java死锁,建造,调查和求解的概念,以帮助程序员了解死锁。
两个或多个线程保留对方要求的资源(锁),当他们等待对方在继续执行之前执行时,它们被称为死锁。结果,这两个过程都在无限的等待中。通常,有多个锁定对象,是由不一致的锁序列引起的。
例如,这两个线程分别使用两个锁A和B。第一个线程是获取锁定顺序A和B,螺纹两个获得锁定顺序b并a。锁定后,他们持有另一方所需的锁,他们无法积极释放自己的锁。目前,死锁!死锁的底层基于锁定的特征。后面的螺纹将进入等待队列!以了解锁的底部,需要JVM的知识和并发知识。本文不介绍本文。
死锁有四个必要的条件。只要系统发生,就必须建立上述四个条件。
实际上,循环循环的建立包含前三个条件的建立。看来没有必要列出这些条件。我觉得这四个条件我只是帮助加深死去的锁,每个人都可以理解记忆!
以下是一个死锁样本,这主要是由于获得资源(锁)的顺序不一致。
运行一段时间后,您可以发现控制台不再输出。
当我们遇到死锁的问题时,我们很容易感觉到莫名其妙,而且问题很困难。从基础上,当僵局发生僵局时,主要的表现是相关线程不再起作用,但没有异常。
以下三种方法可以帮助我们检测到死锁。
JSTACK命令用于生成虚拟机当前力矩的线程快照。
线程快照是虚拟机中每个线程中堆叠的方法。生成线程快照的主要目的是找到长期停顿的原因,例如线程 - 锁定周期,长时间要求外部资源。Jstack比JConsole更原始,并且没有图形接口。
JSTACK格式:
控制台输入JPS以找到死锁的过程
控制台输入JSTACK -L 108(108是Dead Lock过程的PID)。到达线程堆栈信息,将其拉到底部,您可以找到僵局的信息。我们可以看到这两个线程保留了由另一方需要彼此的资源,因此发生僵局。
JConsole是从Java 5引入的,JConsole是一个内置的Java Performance Analyzer。我们可以监视Java应用程序的性能并跟踪Java中的代码,包括死锁检测。
打开CMD窗口并运行jconsole命令。您可以看到pop -up jconsole窗口,选择本地进程,选择僵局的过程,单击连接,如果“安全连接失败”,然后选择“不安全连接””。
单击“线程”,然后单击“死锁检查”。您可以检测到死锁的线程
单击以选择僵局线程,在右侧弹出特定信息,彼此切换。您可以查看僵局信息
JVisualVM是JConsole的高端升级版本。
控制台输入JVisualVM和图形接口将弹出。
在左侧找到死锁的过程。双击,检测结果将在右侧弹出。
单击线程,我们可以在这里看到“死锁”仍然相对聪明,单击线程转储以查看特定的僵局信息
**将信息从底部提取,并找到僵局的详细信息。它与前一个一致。
有一些方法,例如锁定顺序,要求时间限制,等待中断等方法,以解决死锁的通用方法。
当使用多线程时,避免死锁的一种非常简单的方法是统一每个线程中获取锁的顺序,并强制线程以指定顺序获得锁。因此,如果所有线程都以相同的顺序获取并释放锁,不会有死锁。这需要程序员的谨慎性。
避免死锁的另一种方法是在尝试获取锁定时添加超时,这意味着,如果在锁定过程中超过时间限制,则线程放弃锁定请求。如果在内部未成功获得线程给定的时间限制,所有所需的锁将被撤退和获得的所有可用锁,然后在尝试之前等待随机时间。
当然,同步没有此功能,但是我们可以在JDK1.5提供的锁定锁定系统中使用Trylock方法来尝试获取锁定。此方法可以指定超时时间限制。等待时间限制后,它将返回到故障信息。
锁锁,JDK1.5之后提供的新锁!比使用同步方法和语句要多的锁定操作!该实现允许更灵活的结构,并具有尝试获取锁的方法,如下所示:
例子:
从打印结果中,我们可以看到使用此方法将不再产生死锁,但是控制台的输出速度很慢,会影响效率。因此,我们可以使用Trylock()方法。此方法没有等待时间的要求。故障将直接返回。效率更高。效率更高。这次不再进行演示。
在主方法中,主线程主是休眠。目前,这两个线程处于死锁状态。在下一行中,由于T2线程被中断,T2将放弃lock1的应用程序,并同时放置Love2。此操作导致Ti线程成功获得Lock2并继续执行。最终结果是:
中断后,两个线程退出。
如果根本没有僵局,我们也可以使用无锁定编程的方法。Java中的无锁编程主要使用CAS方法。无锁编程的难度相对较高。因此,JDK1.8中的JUC袋的许多类别是无锁的编程算法,例如原子原子和同意下的所有原子类。我们可以使用现成的制作库进行编程。
CAS的原则:在 - 深度分析和施用案例中,Java CAS操作的实施原理。
另一点是,当使用CAS无锁定编程时,我们直接操作是对象的对象(内存地址),因为我们需要根据对象字段的内存地址来更新数据。我们知道直接操作指针非常危险,包括C,C ++和Java直接“取消”指针的概念,但我们仍然可以使用不安全的类操作对象内存(特定的简介可以看到我的博客Java-java- consurent-juc中的不安全类),但是一点关注可能会导致该程序崩溃,这也是我们自己在没有编程的情况下实施CA的困难。
但是,许多著名的类图书馆或组件都使用CAS,例如Kafka,Netty,我们可以查看它们的源代码以增强我们的理解。
对于不执行多线程编程的程序员,可能不会遇到死锁;对于经常处理多线程编程的程序员来说,死锁可能很少从未遇到过)。如果我们以后真的遇到了它,我们可以快速解决它,然后有一个很好的机会。此外,面试也可能不问吗?
如果您不理解或不需要交流,可以发出消息。此外,我想喜欢,收集和关注,我将继续更新各种Java学习博客!