从技术上讲,Java中的线程自身可能死锁吗?
不久前,我在一次采访中被问到这是不可能的,但采访者告诉我这是可能的。不幸的是,我无法获得他的方法来解决这种僵局。
这让我开始思考,我唯一能想到的就是发生这种情况的地方是您拥有一个RMI服务器进程,其中包含一个调用自身的方法。调用该方法的代码行放置在同步块中。
甚至有可能还是面试官不正确?
我一直在考虑的源代码遵循这些原则(其中testDeadlock在RMI服务器进程中运行)
public boolean testDeadlock () throws RemoteException {
synchronized (this) {
//Call testDeadlock via RMI loopback
}
}
JVM仅跟踪具有监视器的本地线程,如果调用类对其自身进行外部调用,则传入调用将导致原始线程自身死锁。
您应该能够运行此代码来说明这个想法
import java.rmi.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.*;
public class DeadlockThreadExample {
public static interface DeadlockClass extends Remote {
public void execute() throws RemoteException;
}
public static class DeadlockClassImpl extends UnicastRemoteObject implements DeadlockClass {
private Object lock = new Object();
public DeadlockClassImpl() throws RemoteException {
super();
}
public void execute() throws RemoteException {
try {
System.out.println("execute()::start");
synchronized (lock) {
System.out.println("execute()::Entered Lock");
DeadlockClass deadlockClass = (DeadlockClass) Naming.lookup("rmi://localhost/DeadlockClass");
deadlockClass.execute();
}
System.out.println("execute()::Exited Lock");
} catch (NotBoundException e) {
System.out.println(e.getMessage());
} catch (java.net.MalformedURLException e) {
System.out.println(e.getMessage());
}
System.out.println("execute()::end");
}
}
public static void main(String[] args) throws Exception {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
DeadlockClassImpl deadlockClassImpl = new DeadlockClassImpl();
Naming.rebind("DeadlockClass", deadlockClassImpl);
DeadlockClass deadlockClass = (DeadlockClass) Naming.lookup("rmi://localhost/DeadlockClass");
deadlockClass.execute();
System.exit(0);
}
}
程序的输出看起来像
execute()::start
execute()::Entered Lock
execute()::start
此外,该线程还转储显示以下内容
"main" prio=6 tid=0x00037fb8 nid=0xb80 runnable [0x0007f000..0x0007fc3c]
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:235)
- locked <0x02fdc568> (a java.io.BufferedInputStream)
at java.io.DataInputStream.readByte(DataInputStream.java:241)
"RMI TCP Connection(4)-172.17.23.165" daemon prio=6 tid=0x0ad83d30 nid=0x1590 waiting for monitor entry [0x0b3cf000..0x0b3cfce8]
at DeadlockThreadExample$DeadlockClassImpl.execute(DeadlockThreadExample.java:24)
- waiting to lock <0x0300a848> (a java.lang.Object)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
"RMI TCP Connection(2)-172.17.23.165" daemon prio=6 tid=0x0ad74008 nid=0x15f0 runnable [0x0b24f000..0x0b24fbe8]
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:235)
- locked <0x02ffb6d8> (a java.io.BufferedInputStream)
at java.io.DataInputStream.readByte(DataInputStream.java:241)
这表明线程确实已经成功锁定了自己
问题内容: 我们遇到了一个奇怪的问题,其中似乎有两个线程正在调用,然后在方法内部永远等待。从外部看,内部看起来像是一个僵局。 到目前为止,我们只看到这种情况发生一次。 谁能想到任何可能导致这些症状的东西? 编辑 :相关线程的线程转储在这里: 问题答案: 可能不是您想要的答案,但这可能是JVM错误。看到 http://bugs.sun.com/bugdatabase/view_bug.do?bug_
问题内容: 如果我在Thread对象上使用start()并且run()方法返回,是否可以再次调用start()? 例如, 我只是想知道是因为我的代码抛出了IllegalThreadStateExceptions,所以想知道是否是因为您不能执行上述操作。 问题答案: 不,你不能。该方法的Javadoc 告诉您!
我使用test_and_set方法让其他线程先等待,线程t1可以中断while循环,但即使在线程t1将值设置为0之后。线程t2继续运行while循环,它不会中断while循环。应该做哪些改变?。
问题内容: 该代码实际上是从Java并发中获取的,根据作者的说法,这里发生了“ ThreadStarvtionDeadlock”。请帮我找到ThreadStarvationDeadlock在这里和哪里发生的情况吗?提前致谢。 问题答案: 死锁和饥饿发生在以下行: 怎么样? 如果我们在程序中添加一些额外的代码,它将发生。可能是这样的: 导致死锁的步骤: 通过实现的类将任务提交给渲染页面。 开始在单独
ConsumerThread1-[topic1-0,topic2-0,topic3-0] ConsumerThread2-[topic1-1,topic2-1,topic3-1] 但是,我们希望每个主题有一个使用者线程,而不是每个分区有一个KafkaListener(或使用者线程)。例如: ConsumerThread1-[topic1-0,topic1-1] ConsumerThread2-[t
我有一个fortran子程序。它一启动就运行相当长的时间。 现在,我想编写一个程序,它在一个线程中从C++调用fortran子程序。当用户请求时,线程应该停止(或取消)。但子程序不支持任何方法在运行过程中终止计算。 操作系统:Windows 7 64位或以上 编译器:MSVC 2015 for C++,Intel Parallel Studio for Fortran