Deadlock of Java concurrent programming

Source: Internet
Author: User
Tags comparable

Dynamic Lock Sequence Deadlock

This is the last one to write. For the convenience and the code again, because the next day I found that the lock sequence to avoid the deadlock of the program is still problematic.

My question is:

The value of an object's hashcode should be fixed, then. Although this code regulates the lock order through hashcode, when two people transfer money to each other's account. No, it turned out to be

public void TransferMoney (account formaccaount, account Toaccount,dollaramount amount) {synchronized (Formaccaount) { Synchronized (Toaccount) {if (Formaccaount.getBalance.compareTo (amount) < 0) {throw new Insufficientfundsexcetion () ;} else {fromaccount.debit (amount); Toaccount.credit (amount);}}}

Such a code. Because it is still FROMACCT and TOACCT exchange a position ah. Later think carefully, haha really want less, because Fromacct and Toacct Exchange position, then actually inside of nested lock also change, although the name seems different, but if two people each other to each other, the order of the lock is the same.

    public class Testlock {private static final object Tielock = new Object ();          Private account Fromacct;                Private account Toacct;              public void TransferMoney (final account Fromacct, final account Toacct, final Dollaramount amount) {              This.fromacct = Fromacct;              This.toacct = Toacct; Class Helper {public void transfer () {if (Fromacct.getbalance (). CompareTo (amount)                      < 0) {throw new insufficientfundsexcetion ();                          } else {fromacct.debit (amount);                      Toacct.credit (amount);              }}} int fromhash = System.identityhashcode (FROMACCT);              int tohash = System.identityhashcode (TOACCT); if (Fromhash < Tohash) {synchronized (FROMACCT) {SynchronizEd (toacct) {new Helper (). Transfer ();                      }}} and else if (Fromhash > Tohash) {synchronized (TOACCT) {                      Synchronized (FROMACCT) {new Helper (). Transfer (); }}} else {synchronized (Tielock) {synchronized (FR                          OMACCT) {synchronized (TOACCT) {new Helper (). Transfer (); }}}}} private class Dollar Amount {} Private abstract class Account {comparable<dollaramount> Getb                      Alance () {return new comparable<dollaramount> () {@Override public int compareTo (Dollaramount o) {//TODO auto-generated Method stub return 0;              }                  };                    } abstract void Debit (Dollaramount a);          abstract void Credit (Dollaramount a);   }      }


Deadlocks that occur between collaboration objects

Taking taxi commissioning system as an example

Import Java.awt.graphics;import java.awt.image;import Java.awt.point;import Java.awt.image.imageobserver;import Java.awt.image.imageproducer;import Java.util.hashset;import java.util.set;class Taxi {Private point location, Destination;private final Dispather dispather;public Taxi (Dispather dispather) {super (); this.dispather = Dispather;} /** * @return The location */public synchronized Point getLocation () {return location;} /** * @param location * The location to set */public synchronized void setlocation (point location) {This.locati On = location;if (location.equals (destination)) {dispather.notifyavailable (this);}}} Class Dispather {Private final set<taxi> taxis;private final set<taxi> availabletaxis;public Dispather () { Taxis = new hashset<taxi> (); availabletaxis = new hashset<taxi> ();} Public synchronized void notifyavailable (Taxi Taxi) {availabletaxis.add (Taxi);} Public synchronized Image GetImage () {Image image = new Image (), for (Taxi T:taxis) {IMAGE.DRawmarker (T.getlocation ());} return image;}}


The lock sequence is very discreet:

In fact, the last is a simple lock sequence deadlock, for synchronized may be more familiar with the synchronized (object) {} method of use, for the Synchronized method is not familiar with, for each object has a lock, You can understand this synchronized (class test{private int, a, b.;}); So when a method within an object is called, the lock of the object is held, regardless of which method of invoking the object waits for the method being called to execute.

The following can explain the cause of the deadlock between collaboration objects:

Taxi calls setlocation while Dispather calls GetImage. This can happen at the same time:

SetLocation acquires the taxi lock first, then acquires the lock of the dispather (because it calls the Notifyavailable method)

While

GetImage acquires the Dispather lock first, then acquires the taxi lock in turn, and when it gets to the taxi that is being called setlocation, the deadlock occurs.

Workaround: Use a similar client-lock method to change the interface to open invocation.

Import Java.awt.graphics;import java.awt.image;import Java.awt.point;import Java.awt.image.imageobserver;import Java.awt.image.imageproducer;import Java.util.hashset;import java.util.set;class Taxi {Private point location, Destination;private final Dispather dispather;public Taxi (Dispather dispather) {super (); this.dispather = Dispather;} /** * @return The location */public synchronized Point getLocation () {return location;} /** * @param location * The location to set */public void setlocation (Point location) {Boolean reached = false; Synchronized (this) {this.location = location;reached = location.equals (destination);} if (reached) {dispather.notifyavailable (this);}}} Class Dispather {Private final set<taxi> taxis;private final set<taxi> availabletaxis;public Dispather () { Taxis = new hashset<taxi> (); availabletaxis = new hashset<taxi> ();} Public synchronized void notifyavailable (Taxi Taxi) {availabletaxis.add (Taxi);} Public Image getImage () {set<taxi> COpy;synchronized (this) {copy = new hashset<taxi> (taxis);} Image image = new image (); for (Taxi t:copy) {Image.drawmarker (t.getlocation ());} return image;}}

Effect:

Reduce the two locks in order to compete only dispather a lock. Dispather never holds a taxi lock. It calls a copy of the taxis.

Because GetImage is used only to fetch data, it does not execute the method of the set class.

In addition, shrinking the protection range of the synchronous code block can also improve scalability.


Avoidance and diagnosis of deadlocks

Although it is possible for a concurrency guru to have a deadlock due to the careless procedure, there are many reasons for deadlocks, like the one above that is very difficult to find because of the deadlock between the collaboration objects. So we should try to avoid the interaction of the lock when we write the procedure. At the same time, open calls should be used whenever possible.

support for timed locks

This technique can detect deadlocks and recover from deadlocks. That is, the lock class is explicitly used to replace the built-in lock mechanism with the timing trylock function. An explicit lock can set a time-out time-out.

This interface was found in the lock class:

Boolean Trylock (long time, Timeunit unit) throws Interruptedexception;
First of all, we'll discuss it later.

parsing deadlocks with thread dump information

The JVM uses thread dumps to help identify the occurrence of deadlocks.

UNIX can send a sigquit signal to the JVM's process or press ctrl-\ on the UNIX platform. The Windows platform presses the Ctrl+break (this break key notebook is not.) Only 87 keys and above the keyboard has. Typically used to debug a server. )


other risk of activityHunger

That is, the thread that is going to perform the task is forced to wait for the priority, and so on, causing the hunger wait.

You can often find that a program calls Thread.Sleep and Thread.yield in some strange places, because the program tries to overcome priority tuning or responsiveness issues, and lets lower-priority threads do more time


To avoid using thread precedence, because this increases platform dependencies. and may lead to active issues


Poor responsiveness

And hunger is a kind of problem, if the GUI application uses the background thread, then this kind of problem is very common.


Live Lock

A live lock is another form of activity that, while not blocking threads, cannot continue because the thread will continue to perform the same operation repeatedly. And it always fails.

A live lock typically occurs in an application that processes transactional messages, and if a message cannot be successfully processed, the message-handling mechanism rolls back the entire transaction. And put it back at the beginning of the queue. So the program doesn't die. But it's not going to work.

The book gave a very image of the chestnut, two people walk met, and then avoid each other, the results in another road met, and constantly repeating.

The solution to this problem is to introduce randomness into the retry mechanism. For example, if two machines attempt to send packets using the same carrier (that is, if the frequency is the same, aliasing occurs, causing the transmission signal to be distorted), then the packets will collide. And then try again. After introducing a random concept, let them retry after waiting for a random period of time. The Ethernet protocol defines an exponential fallback mechanism for recurring conflicts, which reduces the risk of congestion and repeated failures between multiple conflicting machines.

In concurrent applications, we can avoid the occurrence of live locks by allowing the program to wait for a random length of time.














Deadlock of Java concurrent programming

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.