java implementation deadlock sample code

  • 2021-01-06 00:33:17
  • OfStack

What is a deadlock

Let's take a look at an example from daily life: there is a bridge over a river. The bridge deck is narrow enough for only one car to pass, but it is not possible for two cars to pass in parallel. If there are two cars, A and B, respectively, driving on the bridge from both ends of the bridge, then A will have to wait for B to give up the right side of the bridge before crossing the bridge. At this time, A will not move forward. For the B, it crosses the right part of the bridge deck and must wait for the A to give up the left part of the bridge deck. At this point, the B cannot move forward. The cars on both sides didn't back up, so each side waited for the other to clear the bridge, but if neither side gave way, the waiting would be endless. This phenomenon is known as a deadlock. If the car is compared to a process and the bridge deck is a resource, then the above problem can be described as: process A has the resource R1, waiting for process B has the resource Rr; Process B holds resource Rr, waiting on process A holds resource R1. The resources R1 and Rr can only be occupied by one process, that is, two processes are not allowed to occupy at the same time. As a result, neither process can continue execution, and if nothing else is done, this circular wait situation can continue indefinitely, resulting in a process deadlock.

Deadlocks may occur in computer systems involving both software and hardware resources. For example, there is only one CD-ROM drive and one printer in the system, and a process occupies the CD-ROM drive and requests the printer. Another process took possession of the printer and also claimed CD-ROM. As a result, both processes are blocked and can never unblock on their own.

A deadlock is a situation in which several processes are locked indefinitely waiting for the resources they possess. Obviously, if there is no external force, the processes involved in the deadlock will remain locked forever. As can be seen from the above example, the fundamental cause of deadlocks in computer systems is limited resources and improper operation. That is, the first reason is that the system provides too few resources, far unable to meet the needs of concurrent processes for resources. This deadlocks caused by competing resources are at the heart of our discussion. For example, a message is a temporary resource. At some point, process A is waiting for a message from process B, process B is waiting for a message from process C, and process C is waiting for a message from process A. A, B, C3 processes are not able to move forward. Deadlocks on process communication may also occur. Another cause is deadlocks caused by processes advancing in the wrong order. Less resources may not be a fixed birth and death lock. Just like two people across the single-log bridge, if two people have to go first, the deadlock on the single-log bridge is not willing to retreat, it will inevitably produce deadlock in competition with resources; However, if two people go on the bridge first to see if there is anyone on the other side of the bridge, and only go on the bridge when there is no one on the other side, then the problem is solved. Deadlocks can also occur if the program is not designed properly, causing processes to advance in the wrong order.

A deadlock

The deadlock will occur only if the thread ES47en1 occupies ES48en1 and also needs ES49en2, and ES50en2 occupies ES51en2 and also needs ES52en1.

The following code ES55en1 thread occupies ES56en1, and only after acquiring ES57en2 object will it release ES58en1, while the ES59en2 thread first occupies ES60en2 and then fetches ES61en1. At this time, ES62en1 is occupied by ES63en1 thread, ES64en2 is occupied by ES65en2 thread, and both ES66en1 and ES67en2 are waiting indefinitely, so there will be a deadlock.


package javasimple;
/**
 *  A deadlock demo
 * @author haokui
 *
 */
public class DieSynchronized {
 public static void main(String[] args) {
  /**
   *  Create and start two threads t1 , t2 . Both threads need to be shared o1 , o2 Two objects 
   */
  Object o1 = new Object();
  Object o2 = new Object();
  Thread t1 = new Thread(new T1(o1,o2));
  Thread t2 = new Thread(new T2(o1,o2));
  t1.start();
  t2.start();
 }
}
// Create two thread classes 
class T1 implements Runnable {
 Object o1;
 Object o2;
 public T1(Object o1, Object o2){
  this.o1 = o1;
  this.o2 = o2;
 }
 public void run() {
  // The lock o1 and o2
  synchronized (o1) {
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   synchronized (o2) {
    System.out.println("o2");
   }
  }
 }
}
class T2 implements Runnable {
 Object o1;
 Object o2;
 public T2(Object o1, Object o2){
  this.o1 = o1;
  this.o2 = o2;
 }
 public void run() {
  synchronized (o2) {
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   synchronized (o1) {
    System.out.println("o1");
   }
  }
  
 }
}

Note: Concurrency occurs only if o1 and o2 are shared. The two objects can be shared through constructors.


Related articles: