Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the problem of Java deadlock

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

Today, the editor will share with you the relevant knowledge points about how to solve the Java deadlock problem. The content is detailed and the logic is clear. I believe most people still know too much about this, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.

Foreword:

Deadlock (Dead Lock) refers to two or more computing units (processes, threads, or coprograms) that are waiting for each other to stop execution in order to obtain system resources, but no one exits in advance, which is called deadlock.

The example deadlock code is as follows:

Public class DeadLockExample {public static void main (String [] args) {Object lockA = new Object (); / / create lock An Object lockB = new Object () / / create lock B / / create thread 1 Thread T1 = new Thread (new Runnable () {@ Override public void run () {synchronized (lockA) {System.out.println ("Thread 1: get lock A!"); try {Thread.sleep (1000) } catch (InterruptedException e) {e.printStackTrace ();} System.out.println ("Thread 1: waiting to acquire B..."); synchronized (lockB) {System.out.println ("Thread 1: get Lock B!") }); t1.start () / / run thread / / create thread 2 Thread T2 = new Thread (new Runnable () {@ Override public void run () {synchronized (lockB) {System.out.println ("Thread 2: get lock B!"); try {Thread.sleep (1000) } catch (InterruptedException e) {e.printStackTrace ();} System.out.println ("Thread 2: waiting to acquire A..."); synchronized (lockA) {System.out.println ("Thread 2: get Lock A!") }); t2.start (); / / running thread}}

The implementation results of the above procedures are as follows:

As can be seen from the above results, both thread 1 and thread 2 are in a deadlock state, waiting for each other to release the lock.

From the analysis of the above example, it can be concluded that the following four conditions need to be met to generate a deadlock:

Mutual exclusion condition: means that an operation unit (process, thread, or co-program) is exclusive to the allocated resources, that is, a lock resource can only be occupied by one operation unit in a period of time.

Request and retention condition: means that the computing unit has maintained at least one resource, but a new resource request has been made, and the resource has been occupied by other computing units, and the requested computing unit is blocked at this time. But hold on to the other resources you have acquired.

Inalienable condition: refers to the resources that have been obtained by the computing unit and cannot be deprived until they are used up.

Loop waiting condition: when a deadlock occurs, there must be a circular chain of computing units and resources, that is, the computing unit is waiting for the resources occupied by another computing unit, while the other party is waiting for the resources occupied by itself. resulting in loop waiting.

Only when these four conditions are met at the same time will it cause the problem of deadlock.

That is to say, in order to produce a deadlock, we must meet the above four conditions at the same time, then we can solve the deadlock problem by breaking any one of the conditions.

Analysis of deadlock solution

Next, let's analyze the four conditions that lead to deadlocks, which of which can be broken? What can't be destroyed?

Mutual exclusion condition: system characteristics, can not be destroyed.

Request and hold conditions: can be broken.

Inalienable condition: the characteristics of the system can not be destroyed.

Loop waiting condition: can be destroyed.

From the above analysis, we can draw a conclusion that we can only solve the deadlock problem by breaking the request and holding conditions or loop waiting conditions.

Solution 1: sequential locks

The so-called sequential lock refers to solving the deadlock problem by acquiring the lock sequentially so as to avoid the loop waiting condition.

When we do not use sequential locks, the execution of the program may look like this:

Thread 1 first acquires lock A, then lock B, thread 2 executes at the same time with thread 1, thread 2 first acquires lock B, and then acquires lock A, so that both sides first occupy their own resources (lock An and lock B). Then try to acquire each other's lock, resulting in the problem of loop waiting, and finally the problem of deadlock.

At this point, we only need to unify the order in which thread 1 and thread 2 acquire locks, that is, after thread 1 and thread 2 execute at the same time, both acquire lock An and then lock B. the execution process is shown below:

Because only one thread can successfully acquire lock A, the thread that does not acquire lock A will wait to acquire lock A first, and the thread that gets lock A will continue to acquire lock B because there is no thread scrambling and owning lock B. then the thread that gets lock A will successfully own lock B, then execute the corresponding code and release all lock resources, and then another thread waiting for lock A can successfully acquire lock resources. Execute the subsequent code so that there is no deadlock problem.

The implementation code for the sequential lock is as follows:

Public class SolveDeadLockExample {public static void main (String [] args) {Object lockA = new Object (); / / create lock An Object lockB = new Object () / / create lock B / / create thread 1 Thread T1 = new Thread (new Runnable () {@ Override public void run () {synchronized (lockA) {System.out.println ("Thread 1: get lock A!"); try {Thread.sleep (1000) } catch (InterruptedException e) {e.printStackTrace ();} System.out.println ("Thread 1: waiting to acquire B..."); synchronized (lockB) {System.out.println ("Thread 1: get Lock B!") }); t1.start () / / run thread / / create thread 2 Thread T2 = new Thread (new Runnable () {@ Override public void run () {synchronized (lockA) {System.out.println ("Thread 2: get lock A!"); try {Thread.sleep (1000) } catch (InterruptedException e) {e.printStackTrace ();} System.out.println ("Thread 2: waiting to acquire B..."); synchronized (lockB) {System.out.println ("Thread 2: get Lock B!") }); t2.start (); / / running thread}}

The implementation results of the above procedures are as follows:

From the above implementation results, we can see that the program does not have the problem of deadlock.

Solution 2: polling lock

Polling lock avoids deadlock by breaking the "request and hold condition". Its implementation idea is simply to attempt to acquire the lock through polling. If a lock acquisition fails, all locks owned by the current thread are released. Wait for the next round before trying to acquire the lock.

The implementation of polling lock needs to use the tryLock method of ReentrantLock. The specific implementation code is as follows:

Import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class SolveDeadLockExample {public static void main (String [] args) {Lock lockA = new ReentrantLock (); / / create lock A Lock lockB = new ReentrantLock () / / create lock B / / create thread 1 (using polling locks) Thread T1 = new Thread (new Runnable () {@ Override public void run () {/ / call polling lock pollingLock (lockA, lockB);}}); t1.start () / / running thread / / creating thread 2 Thread T2 = new Thread (new Runnable () {@ Override public void run () {lockB.lock (); / / locking System.out.println ("Thread 2: get lock B!"); try {Thread.sleep (1000) System.out.println ("Thread 2: waiting to acquire A..."); lockA.lock (); / / Lock try {System.out.println ("Thread 2: get Lock A!");} finally {lockA.unlock () / / release lock}} catch (InterruptedException e) {e.printStackTrace ();} finally {lockB.unlock (); / / release lock}); t2.start () / / running thread} / * polling lock * / public static void pollingLock (Lock lockA, Lock lockB) {while (true) {if (lockA.tryLock ()) {/ / attempt to acquire lock System.out.println ("Thread 1: get lock A!") Try {Thread.sleep (1000); System.out.println ("Thread 1: waiting to get B...") If (lockB.tryLock ()) {/ / attempt to acquire lock try {System.out.println ("Thread 1: get lock B!");} finally {lockB.unlock () / / release lock System.out.println ("Thread 1: release lock B."); break;} catch (InterruptedException e) {e.printStackTrace () } finally {lockA.unlock (); / / release lock System.out.println ("Thread 1: release lock A.");}} / / wait one second before continuing with try {Thread.sleep (1000) } catch (InterruptedException e) {e.printStackTrace ();}

The implementation results of the above procedures are as follows:

These are all the contents of the article "how to solve the Java deadlock problem". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report