出现死锁情况并建议我如何修复,我需要一般建议
there are caused deadlock condition and advise me how to fix and i need general advises
我学习 java 多线程。出现了死锁情况,建议我如何解决,我需要一般建议。
我明白死锁概念是什么意思,但它可以解决一个问题。
这是代码:
java 效用 class:
// in multithreading.
class Util
{
// Util class to sleep a thread
static void sleep(long millis)
{
try
{
Thread.sleep(millis);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
java 共享 class:
// This class is shared by both threads
class Shared
{
// first synchronized method
synchronized void test1(Shared s2)
{
System.out.println("test1-begin");
Util.sleep(1000);
// taking object lock of s2 enters
// into test2 method
s2.test2(this);
System.out.println("test1-end");
}
// second synchronized method
synchronized void test2(Shared s1)
{
System.out.println("test2-begin");
Util.sleep(1000);
// taking object lock of s1 enters
// into test1 method
s1.test1(this);
System.out.println("test2-end");
}
}
java 线程 1 class:
class Thread1 extends Thread
{
private Shared s1;
private Shared s2;
// constructor to initialize fields
public Thread1(Shared s1, Shared s2)
{
this.s1 = s1;
this.s2 = s2;
}
// run method to start a thread
@Override
public void run()
{
// taking object lock of s1 enters
// into test1 method
s1.test1(s2);
}
}
java 线程 2 class:
class Thread2 extends Thread
{
private Shared s1;
private Shared s2;
// constructor to initialize fields
public Thread2(Shared s1, Shared s2)
{
this.s1 = s1;
this.s2 = s2;
}
// run method to start a thread
@Override
public void run()
{
// taking object lock of s2
// enters into test2 method
s2.test2(s1);
}
}
最终 GFC class 主要方法:
public class GFG
{
public static void main(String[] args)
{
// creating one object
Shared s1 = new Shared();
// creating second object
Shared s2 = new Shared();
// creating first thread and starting it
Thread1 t1 = new Thread1(s1, s2);
t1.start();
// creating second thread and starting it
Thread2 t2 = new Thread2(s1, s2);
t2.start();
// sleeping main thread
Util.sleep(2000);
}
}
您提供的代码确实会导致死锁。最初,t1
获得 s1
的内在锁,t2
获得 s2
的锁。然后 t1
尝试获取 s2
锁,同时仍然持有 s1
锁。由于s2
锁被t2
持有,t1
会阻塞等待锁被释放。类似的情况发生在 t2
中:它尝试获取 s1
锁,同时仍然持有 s2
锁。由于 s1
锁由 t1
持有,因此 t2
也会阻塞。这会导致死锁。
要解决这个问题,两个线程应该只使用一个锁来同步它们的工作。一个可能的解决方案是:
class Shared
{
private static final Object LOCK = new Object();
// first synchronized method
void test1(Shared s2)
{
synchronized (LOCK) {
System.out.println("test1-begin");
Util.sleep(1000);
// taking object lock of s2 enters
// into test2 method
s2.test2(this);
System.out.println("test1-end");
}
}
// second synchronized method
void test2(Shared s1)
{
synchronized (LOCK) {
System.out.println("test2-begin");
Util.sleep(1000);
// taking object lock of s1 enters
// into test1 method
s1.test1(this);
System.out.println("test2-end");
}
}
}
这将修复死锁。但是,考虑到目前的实现,会导致间接递归造成的死循环: s1.test1(s2)
-> s2.test2(s1)
-> s1.test1(s2)
-> s2.test2(s1)
-> ...
我学习 java 多线程。出现了死锁情况,建议我如何解决,我需要一般建议。 我明白死锁概念是什么意思,但它可以解决一个问题。 这是代码:
java 效用 class:
// in multithreading.
class Util
{
// Util class to sleep a thread
static void sleep(long millis)
{
try
{
Thread.sleep(millis);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
java 共享 class:
// This class is shared by both threads
class Shared
{
// first synchronized method
synchronized void test1(Shared s2)
{
System.out.println("test1-begin");
Util.sleep(1000);
// taking object lock of s2 enters
// into test2 method
s2.test2(this);
System.out.println("test1-end");
}
// second synchronized method
synchronized void test2(Shared s1)
{
System.out.println("test2-begin");
Util.sleep(1000);
// taking object lock of s1 enters
// into test1 method
s1.test1(this);
System.out.println("test2-end");
}
}
java 线程 1 class:
class Thread1 extends Thread
{
private Shared s1;
private Shared s2;
// constructor to initialize fields
public Thread1(Shared s1, Shared s2)
{
this.s1 = s1;
this.s2 = s2;
}
// run method to start a thread
@Override
public void run()
{
// taking object lock of s1 enters
// into test1 method
s1.test1(s2);
}
}
java 线程 2 class:
class Thread2 extends Thread
{
private Shared s1;
private Shared s2;
// constructor to initialize fields
public Thread2(Shared s1, Shared s2)
{
this.s1 = s1;
this.s2 = s2;
}
// run method to start a thread
@Override
public void run()
{
// taking object lock of s2
// enters into test2 method
s2.test2(s1);
}
}
最终 GFC class 主要方法:
public class GFG
{
public static void main(String[] args)
{
// creating one object
Shared s1 = new Shared();
// creating second object
Shared s2 = new Shared();
// creating first thread and starting it
Thread1 t1 = new Thread1(s1, s2);
t1.start();
// creating second thread and starting it
Thread2 t2 = new Thread2(s1, s2);
t2.start();
// sleeping main thread
Util.sleep(2000);
}
}
您提供的代码确实会导致死锁。最初,t1
获得 s1
的内在锁,t2
获得 s2
的锁。然后 t1
尝试获取 s2
锁,同时仍然持有 s1
锁。由于s2
锁被t2
持有,t1
会阻塞等待锁被释放。类似的情况发生在 t2
中:它尝试获取 s1
锁,同时仍然持有 s2
锁。由于 s1
锁由 t1
持有,因此 t2
也会阻塞。这会导致死锁。
要解决这个问题,两个线程应该只使用一个锁来同步它们的工作。一个可能的解决方案是:
class Shared
{
private static final Object LOCK = new Object();
// first synchronized method
void test1(Shared s2)
{
synchronized (LOCK) {
System.out.println("test1-begin");
Util.sleep(1000);
// taking object lock of s2 enters
// into test2 method
s2.test2(this);
System.out.println("test1-end");
}
}
// second synchronized method
void test2(Shared s1)
{
synchronized (LOCK) {
System.out.println("test2-begin");
Util.sleep(1000);
// taking object lock of s1 enters
// into test1 method
s1.test1(this);
System.out.println("test2-end");
}
}
}
这将修复死锁。但是,考虑到目前的实现,会导致间接递归造成的死循环: s1.test1(s2)
-> s2.test2(s1)
-> s1.test1(s2)
-> s2.test2(s1)
-> ...