如何在Java使用线程解决死锁?
如果两个线程永远等待对方,这种无限等待在Java称为死锁。 Synchronized 关键字是死锁情况的唯一原因,因此在使用 synchronized 关键字时我们必须特别小心。没有解决死锁的技术,但有几种预防技术可用。
实现:发生死锁
示例 1:
Java
// Java program to illustrate Deadlock
// where deadlock occurs
// Importing required packages
import java.io.*;
import java.util.*;
// Class 1
// Helper class
class A {
// Method 1 of this class
// Synchronized method
public synchronized void last()
{
// Print and display statement
System.out.println("Inside A, last() method");
}
// Method 2 of this class
// Synchronized method
public synchronized void d1(B b)
{
System.out.println(
"Thread1 start execution of d1() method");
// Try block to check for exceptions
try {
// Putting the current thread to sleep for
// specific time using slep() method
Thread.sleep(2000);
}
// Catch block to handle the exceptions
catch (InterruptedException e) {
// Display the exception on the console
System.out.println(e);
}
// Display statement
System.out.println(
"Thread trying to call B's last() method");
// Calling the method 1 of this class as created
// above
b.last();
}
}
// Class 2
// Helper class B
class B {
// Method 1 of this class
public synchronized void last()
{
// Display statement only
System.out.println("Inside B, last() method");
}
// Method 2 of this class
// Synchronized the method d2
public synchronized void d2(A a)
{
// Display message only
System.out.println(
"Thread2 start execution of d2() method");
// Try block to check for exceptions
try {
// Putting the current thread to sleep for
// certain time using sleep() method
Thread.sleep(2000);
// Catch block to handle the exceptions
}
catch (InterruptedException e) {
// Display the exception on the console
System.out.println(e);
}
// Display message only
System.out.println(
"Thread2 trying to call A's last method");
// Again calling the last() method inside this class
a.last();
}
}
// Class 3
// Main class
// Deadlock class which is extending Thread class
class GFG extends Thread {
// Creating object of type class A
A a = new A();
// Creating object of type class B
B b = new B();
// Method 1
public void m1()
{
// Starting the thread
this.start();
// Calling d1 method of class A
a.d1(b);
}
// Method 2
// run() method for the thread
public void run()
{
// Calling d2 method of class B
b.d2(a);
}
// Method 3
// Main driver method
public static void main(String[] args)
{
// Creating object of this class
GFG deadlock = new GFG();
// Calling m1 method
deadlock.m1();
}
}
Java
// Java program to illustrate Deadlock
// where deadlock is pevented from occuring
// Importing required packages
import java.io.*;
import java.util.*;
// Class 1
// Helper class
class A {
// Method 1 of this class
// Synchronized method
public synchronized void last()
{
// Print and display statement
System.out.println("Inside A, last() method");
}
// Method 2 of this class
// Synchronized method
public synchronized void d1(B b)
{
System.out.println(
"Thread1 start execution of d1() method");
// Try block to check for exceptions
try {
// Putting the current thread to sleep for
// specific time using slep() method
Thread.sleep(2000);
}
// Catch block to handle the exceptions
catch (InterruptedException e) {
// Display the exception on the console
System.out.println(e);
}
// Display statement
System.out.println(
"Thread trying to call B's last() method");
// Calling the method 1 of this class as created
// above
b.last();
}
}
// Class 2
// Helper class B
class B {
// Method 1 of this class
public void last()
{
// Display statement only
System.out.println("Inside B, last() method");
}
// Method 2 of this class
// Non-synchronized the method d2
public void d2(A a)
{
// Display message only
System.out.println(
"Thread2 start execution of d2() method");
// Try block to check for exceptions
try {
// Putting the current thread to sleep for
// certain time using sleep() method
Thread.sleep(2000);
// Catch block to handle the exceptions
}
catch (InterruptedException e) {
// Display the exception on the console
System.out.println(e);
}
// Display message only
System.out.println(
"Thread2 trying to call A's last method");
// Again calling the last() method inside this class
a.last();
}
}
// Class 3
// Main class
// Deadlock class which is extending Thread class
class GFG extends Thread {
// Creating object of type class A
A a = new A();
// Creating object of type class B
B b = new B();
// Method 1
public void m1()
{
// Starting the thread
this.start();
// Calling d1 method of class A
a.d1(b);
}
// Method 2
// run() method for the thread
public void run()
{
// Calling d2 method of class B
b.d2(a);
}
// Method 3
// Main driver method
public static void main(String[] args)
{
// Creating object of this class
GFG deadlock = new GFG();
// Calling m1 method
deadlock.m1();
}
}
输出:
输出说明:
这里光标一直显示,因为线程进入死锁情况。在上面的程序中,如果我们删除了至少一个synchronized关键字,那么程序就不会进入死锁状态。因此,synchronized 关键字是导致死锁情况的主要原因之一。因此,在使用 synchronized 关键字时,我们必须特别小心。
我们可以通过以下方式避免死锁情况:
- 使用 Thread.join() 方法:如果两个线程使用线程连接无限期地等待对方完成,我们可能会遇到死锁。然后我们的线程必须等待另一个线程完成,最好使用 Thread.join() 方法以及您希望等待线程完成的最长时间。
- 使用锁排序:我们必须始终为每个锁分配一个数值,在获取具有较高数值的锁之前,我们必须获取具有较低数值的锁。
- 避免不必要的锁:我们应该只对那些需要锁的成员使用锁,不必要的使用锁会导致死锁情况。并且推荐使用无锁数据结构,如果是 可以使您的代码免于锁定。例如,不要使用同步的 ArrayList,而是使用 ConcurrentLinkedQueue。
示例 2:防止死锁
Java
// Java program to illustrate Deadlock
// where deadlock is pevented from occuring
// Importing required packages
import java.io.*;
import java.util.*;
// Class 1
// Helper class
class A {
// Method 1 of this class
// Synchronized method
public synchronized void last()
{
// Print and display statement
System.out.println("Inside A, last() method");
}
// Method 2 of this class
// Synchronized method
public synchronized void d1(B b)
{
System.out.println(
"Thread1 start execution of d1() method");
// Try block to check for exceptions
try {
// Putting the current thread to sleep for
// specific time using slep() method
Thread.sleep(2000);
}
// Catch block to handle the exceptions
catch (InterruptedException e) {
// Display the exception on the console
System.out.println(e);
}
// Display statement
System.out.println(
"Thread trying to call B's last() method");
// Calling the method 1 of this class as created
// above
b.last();
}
}
// Class 2
// Helper class B
class B {
// Method 1 of this class
public void last()
{
// Display statement only
System.out.println("Inside B, last() method");
}
// Method 2 of this class
// Non-synchronized the method d2
public void d2(A a)
{
// Display message only
System.out.println(
"Thread2 start execution of d2() method");
// Try block to check for exceptions
try {
// Putting the current thread to sleep for
// certain time using sleep() method
Thread.sleep(2000);
// Catch block to handle the exceptions
}
catch (InterruptedException e) {
// Display the exception on the console
System.out.println(e);
}
// Display message only
System.out.println(
"Thread2 trying to call A's last method");
// Again calling the last() method inside this class
a.last();
}
}
// Class 3
// Main class
// Deadlock class which is extending Thread class
class GFG extends Thread {
// Creating object of type class A
A a = new A();
// Creating object of type class B
B b = new B();
// Method 1
public void m1()
{
// Starting the thread
this.start();
// Calling d1 method of class A
a.d1(b);
}
// Method 2
// run() method for the thread
public void run()
{
// Calling d2 method of class B
b.d2(a);
}
// Method 3
// Main driver method
public static void main(String[] args)
{
// Creating object of this class
GFG deadlock = new GFG();
// Calling m1 method
deadlock.m1();
}
}
输出: