Android deadlock and re-entry lock, android deadlock
Deadlock definition: 1. General deadlock generally refers to a deadlock that multiple threads Must have multiple resources at the same time for execution. Because resources required by different threads are occupied by different threads, this is the definition of a deadlock.
package com.cxt.thread; public class TestDeadLock extends Thread{ boolean b; DeadLock lock; public TestDeadLock(boolean b, DeadLock lock) { super(); this.b = b; this.lock = lock; } public static void main(String[] args) { DeadLock lock = new DeadLock(); TestDeadLock t1 = new TestDeadLock(true, lock); TestDeadLock t2 = new TestDeadLock(false, lock); t1.start(); t2.start(); } @Override public void run() { if(this.b){ lock.m1(); } else lock.m2(); } } class DeadLock { Object o1 = new Object(); Object o2 = new Object(); void m1(){ synchronized(o1){ System.out.println("m1 Lock o1 first"); synchronized(o2){ System.out.println("m1 Lock o2 second"); } } } void m2(){ synchronized(o2){ System.out.println("m2 Lock o2 first"); synchronized(o1){ System.out.println("m2 Lock o1 second"); } } } }
As shown in the code, we know that thread t1 and t2 both require the object o1, so that o2 can normally complete the function. However, because the objects they hold are the opposite of the objects they want to obtain, the two threads are deadlocked and eventually lead to deadlocks. Solution: execute another thread after one of the threads is fully executed. Promote to multiple threads and execute multiple threads in a certain order. Another method is to set the priority. If a deadlock occurs in multiple running threads and a rollback with a lower priority occurs, the deadlock problem can be solved by executing the rollback with a higher priority first. 2. Lock the nested Tube
Thread 1 gets the Lock of object. Thread 1 acquires the Lock of object B (holding the Lock of object A at the same time ). Thread 1 Decides to wait for the signal from another thread to continue. Thread 1 calls B. wait () to release the lock on object B, but still holds the Lock of object. Thread 2 needs to hold the Lock of object A and object B at the same time to send A signal to thread 1. Thread 2 cannot obtain the lock on Object A because the lock on Object A is currently being held by thread 1. Thread 2 has been blocked, waiting for thread 1 to release the lock on Object. Thread 1 is always blocked and waits for the signal of thread 2. Therefore, the lock on Object A will not be released, and thread 2 needs the lock on Object A to send A signal to thread 1 ......
Check the Code:
Package com. cxt. lock; import com. cxt. thread. synchronizer; import com. cxt. thread. testLock; // lock implementation with nested monitor lockout problem/*** a zombie nested tube is locked, different from a deadlock */public class Lock {protected MonitorObject monitorObject = new MonitorObject (); protected boolean isLocked = false; public static void main (String [] args) {Lock l = new Lock (); l. isLocked = true; MyRunnable r1 = new MyRunnable (l, 0); MyRunnable r2 = new MyRunnable (l, 0); Thread t1 = new Thread (r1 ); thread t2 = new Thread (r2); t1.start (); t2.start ();/** when, because the other two parameters sometimes cannot capture isLocked = false * // for (int I = 0; I <100; I ++) {// l. isLocked = false; // try {// Thread. sleep (10); //} catch (InterruptedException e) {// e. printStackTrace (); //} public void lock () throws InterruptedException {// when this method is executed, isLocked = true, other methods, whether the lock method is executed or the Unlock method is executed, will cause a pipe deadlock. // The deadlock can be solved only when isLocked is set to false manually. When it is set to false, other threads must detect the deadlock, therefore, you must set synchronized (this) {while (isLocked) {synchronized (this. monitorObject) {this. monitorObject. wait () ;}} isLocked = true ;}} public void unlock () {synchronized (this) {this. isLocked = false; synchronized (this. monitorObject) {this. monitorObject. notify () ;}} static class MyRunnable implements Runnable {Lock l = null; int I; public MyRunnable (Lock l, int I) {this. l = l; this. I = I ;}@ Override public void run () {try {if (I % 2 = 0) {this. l. lock ();} else {this. l. unlock () ;}} catch (InterruptedException e) {e. printStackTrace ();}}}}
We observe the lock () method. When we execute lock (), when isLocked is true, the problem arises. we execute the monitorObject method block, but monitorObject changes to the waiting state, however, this lock is held by this thread. If other threads want to execute lock () or unLock (), there will be an infinite waiting state, this thread is always in the infinite state of waiting for other threads to wake up monitorObject, and eventually remains deadlocked. The solution is to manually set isLocked to false. This is a pitfall, so don't do anything when coding. 3. re-import and lock
Package com. cxt. lock; public class Lock2 {private boolean isLocked = false; public static void main (String [] args) {Lock2 lock = new Lock2 (); MyRunnable r1 = new MyRunnable (lock, true); MyRunnable r2 = new MyRunnable (lock, false); Thread t1 = new Thread (r1); Thread t2 = new Thread (r2); t1.start (); // t2.start ();} public synchronized void lock () throws InterruptedException {while (isLocked) {wait () ;} IsLocked = true;} public synchronized void unlock () {isLocked = false; Policy ();} static class MyRunnable implements Runnable {Lock2 l = null; boolean flag = false; public MyRunnable (Lock2 l, boolean flag) {this. l = l; this. flag = flag;} @ Override public void run () {if (flag = true) try {// if you execute lock () twice in a row (), the system waits infinitely. // the solution is to execute the unLock () method once twice. lock (); System. out. println ("Lock! "); // L. unlock (); // System. out. println (" Unlock! "); L. lock (); System. out. println (" Lock! ");} Catch (InterruptedException e) {e. printStackTrace ();} else l. unlock ();}}}
When you execute lock () twice in a row, the following occurs: for the first time, isLocked is false, and isLocked is set to true after execution. the second time, if isLocked is true, it will be in the infinite waiting state. Solution: Execute the unLock method once between two locks (), or execute the unLock () method once by another thread. [Re-import lock]
Package com. text; public class Lock2 {private boolean isLocked = false; public static void main (String [] args) {Lock2 lock = new Lock2 (); MyRunnable r1 = new MyRunnable (lock, true); MyRunnable r2 = new MyRunnable (lock, false); Thread t1 = new Thread (r1); Thread t2 = new Thread (r2); t1.start (); // t2.start ();} public synchronized void lock () throws InterruptedException {while (isLocked) {System. out. Println ("synchronized wait ()! "); Unlock (); wait ();} isLocked = true; System. out. println (" synchronized lock! ");} Public synchronized void unlock () {isLocked = false; y (); System. out. println (" synchronized unlock! ");} Static class MyRunnable implements Runnable {Lock2 l = null; boolean flag = false; public MyRunnable (Lock2 l, boolean flag) {this. l = l; this. flag = flag;} @ Override public void run () {if (flag = true) try {// if you execute lock () twice in a row (), the system waits infinitely. // the solution is to execute the unLock () method once twice. lock (); System. out. println ("Lock! "); L. lock (); // l. unlock ();// Commented outSystem. out. println ("Lock! ");} Catch (InterruptedException e) {e. printStackTrace ();} else l. unlock ();}}}
Output:
Synchronized lock!
Lock!
Synchronized wait ()!
Synchronized unlock!
When a synchronized method/block calls other synchronized methods/blocks in this class, the lock can always be obtained.
Package com. text; public class Lock2 {private boolean isLocked = false; public static void main (String [] args) {Lock2 lock = new Lock2 (); MyRunnable r1 = new MyRunnable (lock, true); MyRunnable r2 = new MyRunnable (lock, false); Thread t1 = new Thread (r1); Thread t2 = new Thread (r2); t1.start (); // t2.start ();} public synchronized void lock () throws InterruptedException {while (isLocked) {System. out. Println ("synchronized wait ()! "); Wait () ;}islocked = true; System. out. println (" synchronized lock! ");} Public synchronized void unlock () {isLocked = false; y (); System. out. println (" synchronized unlock! ");} Static class MyRunnable implements Runnable {Lock2 l = null; boolean flag = false; public MyRunnable (Lock2 l, boolean flag) {this. l = l; this. flag = flag;} @ Override public void run () {if (flag = true) try {// if you execute lock () twice in a row (), the system waits infinitely. // the solution is to execute the unLock () method once twice. lock (); System. out. println ("Lock! "); L. lock (); l. unlock ();// UncommentSystem. out. println ("Lock! ");} Catch (InterruptedException e) {e. printStackTrace ();} else l. unlock ();}}}
Output:
Synchronized lock!
Lock!
Synchronized wait ()!
Two consecutive lock methods lead to a deadlock for the second time. The third unlock is not called in the synchronized Method/block, so the lock cannot be obtained,