Is it possible that the thread itself has reached a dead end?

How technically possible is it that the thread in Java itself has come to a standstill?

I was asked to answer the interview a while ago and answered that this was not possible, but the interviewer told me that it was. Unfortunately, I could not get his method on how to reach this dead end.

This made me think, and the only situation I can think of is where you can do this when you have an RMI server process that contains a method that calls itself. The line of code that calls the method is placed in a synchronized block.

Is this possible or the wrong interviewer?

The source code I was thinking about was on these lines (where testDeadlock works in the RMI server process)

public boolean testDeadlock () throws RemoteException { synchronized (this) { //Call testDeadlock via RMI loopback } } 
+54
java multithreading deadlock rmi
Aug 16 '10 at 13:14
source share
20 answers

The JVM only tracks the local thread that the monitor has, if the calling class makes an external call back on its own, the incoming call causes the original thread to brake.

You can run this code to illustrate the idea.

 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); } } 

Exiting the program looks like

 execute()::start execute()::Entered Lock execute()::start 

In addition, the stream dump also shows the following

 "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) 

which indicates that the thread really managed to block itself

+4
Sep 08 2018-10-09T00:
source share

Good, based on the definition of:

A dead end is a situation in which two or more competing actions are waiting for another.

I would say that the answer is not sure that a thread can sit there indefinitely for something, however, if two competing actions are not waiting for each other, it is by definition not a dead end.

If someone does not explain to me how one thread can simultaneously wait for two actions to complete?

UPDATE: The only possible situation I can think of is some kind of message pump where the thread is processing a message that asks it to wait indefinitely for something . happens when something is actually processed by another message on the message pump.

This (incredibly contrived) scenario can be technically called a dead end.

+50
Aug 16 '10 at 13:22
source share

It depends on what you mean by a dead end. For example, you can easily wait() on a monitor that won't pulse anything ... but I don't think I would call that dead end as such.

Reflecting on your “methods that calls itself” if your server starts a certain number of threads, all of them may be busy waiting for a response from the same server, if so. (The simplest example: a server uses only one thread for processing. If you write a request handler that calls to the same server, it will wait until a blocked thread completes processing the request before it can serve the same request ...) in fact, this is not a “synchronous” type of dead end, but it is certainly a danger to understanding.

EDIT. To apply this answer to a definition in others, competing actions here will “populate the current request” and “process a new request”. Each action expects a different one.

+18
Aug 16 '10 at 13:18
source share

Perhaps he meant LOCK , which is also too easy:

 synchronized( this ) { wait( ); } 
+10
Aug 16 '10 at 13:19
source share

Perhaps what the interviewer was thinking:

 Thread.currentThread().join(); 

However, I would say that it is not considered a dead end.

+7
Aug 16 '10 at 13:49
source share

Updating from a read lock to a write lock (trying to get a write lock while holding a read lock) will cause the stream to be completely blocked. Is this a dead end? You will be the judge ... But this is the easiest way to create an effect with a single thread.

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

+6
Aug 16 2018-10-16T00:
source share

According to Wikipedia, "A dead end is a situation where two or more competing actions are waiting for another, and therefore never happens."

... "In computer science, Koffman’s deadlock refers to a certain condition when two or more processes are waiting for each other to free a resource, or more than two processes are waiting for resources in a circular chain."

I think two or more are keywords here if you adhere to a strict definition.

+5
Aug 16 '10 at 13:24
source share

A deadlock is a form of resource depletion due to the interaction of several threads.

When a thread enters a resource save state, it refers to an online lock, which is similar to a deadlock, but by definition is not identical.

An example of livelock is using a ReentrantReadWriteLock. Despite the readability of reading or writing, it does not allow updating the lock from read to write.

 public class LiveLock { public static void main(String[] args) { ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); lock.readLock().lock(); if (someCondition()) { // we want to write without allowing another thread to jump in. lock.writeLock().lock(); } } private static boolean someCondition() { return true; } } 

results in the lock process here

 "main" #1 prio=5 os_prio=0 tid=0x0000000002a52800 nid=0x550c waiting on condition [0x000000000291f000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007162e5e40> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199) at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:943) at LiveLock.main(LiveLock.java:10) 



There is a related question; Can a thread go to a standstill without creating additional threads. This is possible because there are background threads, for example, a finalizer thread that can run custom code in the background. This allows the main thread and the finalizer thread to interlock each other.

+5
Nov 05 '18 at 8:12
source share

While I have not used Java, I have already reached the dead end of a single thread application. IIRC: Routine A blocked a piece of data to update it. Routine B also blocked the same piece of data to update it. Due to changing requirements, A ended the call to B. Oops.

Of course, this was a common development error that I caught the first time I tried to run the code, but it made a dead end. I would think that deadlocks of this type would be available in any language that supports the file system.

+2
Aug 16 '10 at 13:52
source share

The answer (Pram's), marked as correct, is not technically a dead end, as others have suggested. He was just blocked.

I would suggest in Java, you can rely on the definition of Java (which is consistent with the idea of ​​two threads). The ultimate judge then can be the JVM if it detects a dead end itself . So, in the Pram example, the stream will show something like the following if it was a brilliant dead end.

 Deadlock detected ================= "Negotiator-Thread-1": waiting to lock Monitor of com.google.code.tempusfugit.concurrency.DeadlockDetectorTest$Cat@ce4a8a which is held by "Kidnapper-Thread-0" "Kidnapper-Thread-0": waiting to lock Monitor of com.google.code.tempusfugit.concurrency.DeadlockDetectorTest$Cash@7fc8b2 which is held by "Negotiator-Thread-1" 

This lock detection has been available for built-in locks with cyclic deadlocks with 1.5 and Lock since 1.6.

A permanently locked resource, or at least something that is waiting for something that will never happen, is called livelock . Similar problems, when processes outside the virtual machine (for example) stall databases, are quite possible, but I would not argue that this is not suitable for the question.

I would be interested to write how the interviewer claims that this is possible ...

In answer to your original question, for two tangos, I suggest that Pram's answer should not be marked as correct, because it did not exist! ;) The RMI thread that calls back can call but it works in a different thread (managed by the RMI server) than in the main one. Two threads are involved, even if the main thread has not explicitly set another. There is no deadlock, as evidenced by the absence of detection in the stream dump (or if you click "deadlock detection" in jconsole), it will be more accurately described as livelock.

Having said all this, any discussion in accordance with each of these answers would be enough to satisfy me as an interviewer.

+2
Dec 31 '10 at 15:26
source share

No, because Java implements reentrancy . But please do not mix concurrency and RMI. Stub synchronization is something completely different than remote objects that are internally synchronized.

+1
Aug 16 '10 at 13:34
source share

You can get into the same Deadlock thread with ReentrantReadWriteLock . Write locks can acquire read locks, but not vice versa. The following will block indefinitely.

  ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); lock.readLock().lock(); lock.writeLock().lock(); 
+1
Nov 08 2018-10-10
source share

Ideally, a thread should never create a deadlock using "synchronized locks" unless there really is an error in the JVM itself, as some people allegedly noticed in older versions

0
Aug 16 '10 at 13:22
source share

Here is the path for the dead end itself.

 public class DeadlockMe { public static void main(String[] args) { DeadlockThing foo = new DeadlockThing(); synchronized(foo) { try { foo.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } 

An instance of the class is created in the stream - any class is waiting for it. Because a thread created an object with a local scope, there is no way that any other thread can notify the object of a waking thread.

0
Aug 16 '10 at 14:51
source share

You write a thread that can receive messages from other threads that say, for example, about completion. You write code in a thread to track other threads and send them completion messages and wait for a response. The thread will find itself in the list, send itself a message to terminate and wait for it to end. If it was not written in such a way that priority incoming messages went into a waiting state ...

0
Aug 16 '10 at 15:07
source share

If you stretch the definition of the term "dead end": one thread may be blocked with non-reentrant blocking, which was required earlier.

0
Aug 16 '10 at 17:45
source share

When a thread enters a synchronized block, it checks whether the current thread is the owner of the lock, and if so, the thread simply continues without waiting.

Therefore, I do not think this is possible.

0
Aug 16 '10 at 18:44
source share

I know this is an old post. Here is another example of how this could happen if your code interacts with external resources:

I have a thread that opens a connection to the database, starts transaction A and starts the update. The same thread, open another connection, start another transaction B. However, since the transaction is not committed yet and it locked the database table, transaction B has access to this locked table, so it must wait

In the end, the same thread itself is a block because it opened more than one database connection.




In the application I work with, a lot of things happened because the application has many modules, and the thread can work with many methods. These methods open their own connections. Since we had different developers, they write their own code, they may not see how their code runs, and therefore they could not see the general database transactions opened by the application.

0
Aug 31 2018-12-12T00:
source share

The interviewer was right. A thread can block itself according to JCIP . But how?

In section 2.3.2 of the JCIP, we have the following paragraph on Reentrancy:

Reentrancy facilitates the encapsulation of lock behavior and thus simplifies the development of object-oriented concurrentcode. Without reentrons, the very natural code in Listing 2.7, in which a subclass overrides the synchronized method and then calls the superclass method, will be deadlock.

Synchronized keyword locking is a reentrant lock, so a thread can lock and unlock in a nested manner, but if you use a lock without a reentrant, as in the following example, I wrote as evidence. You will have a dead end! According to JCIP.

 public class SelfDeadLock { public static class Father{ volatile protected int n = 0; protected Lock ourLock = new Lock(); public void writeSth(){ try { ourLock.lock(); n++; System.out.println("Father class: " + n); } catch (InterruptedException ex) { Logger.getLogger(SelfDeadLock.class.getName()).log(Level.SEVERE, null, ex); } ourLock.unlock(); } } public static class Child extends Father{ @Override public void writeSth() { try { ourLock.lock(); n++; System.out.println("Child class: " + n); super.writeSth(); } catch (InterruptedException ex) { Logger.getLogger(SelfDeadLock.class.getName()).log(Level.SEVERE, null, ex); } ourLock.unlock(); } } public static void main(String[] args) { Child child = new Child(); child.writeSth(); } } 
0
Dec 29 '13 at 3:12
source share

Although the comments here are pedantic about the “dead end” that arises if at least two threads / actions compete for the same resource ... I think the spirit of this issue was to discuss the need for re-blocking - especially in the context "recursive" lock

Here is an example in Python (I'm sure the concept remains the same in Java): If you change RLock to Lock (i.e., re-entering lock to lock, the thread will hang)

 import threading """ Change RLock to Lock to make it "hang" """ lock = threading.Condition(threading.RLock()) def print_list(list): lock.acquire() if not list: lock.release() return print(list[0]) print_list(list[1:]) lock.release() print_list([1, 2, 3, 4, 5]) 
0
Mar 04 '19 at 13:34
source share



All Articles