package multilock.deadlock; /** * https://www.cnblogs.com/silyvin/p/11747303.html * Created by joyce on 2019/10/27. */ public class NotifyDeadLock { private boolean isSub = true; private int count = 0; public synchronized void sub() { try { while (!isSub ) { this.wait(); } System. out.println("sub ---- " + count); isSub = false ; this.notify(); // dead with notify , notifyAll ok } catch (Exception e) { e.printStackTrace(); } count++; } public synchronized void main() { try { while (isSub ) { this.wait(); } System. out.println("main (((((((((((( " + count); isSub = true ; this.notify(); // dead with notify , notifyAll ok } catch (Exception e) { e.printStackTrace(); } count++; } public static void main(String[] args) { // System.out.println("lock"); final NotifyDeadLock ot = new NotifyDeadLock(); for (int j = 0; j < 10; j++) { new Thread(new Runnable() { public void run() { for (int i = 0; i < 5; i++) { ot.sub(); } } }, "mysub").start(); new Thread(new Runnable() { public void run() { for (int i = 0; i < 5; i++) { ot.main(); } } }, "mymain").start(); } } }
输出:
sub ---- 0
main (((((((((((( 1
sub ---- 2
main (((((((((((( 3
sub ---- 4
main (((((((((((( 5
sub ---- 6
main (((((((((((( 7
sub ---- 8
main (((((((((((( 9
sub ---- 10
main (((((((((((( 11
sub ---- 12
main (((((((((((( 13
sub ---- 14
main (((((((((((( 15
sub ---- 16
main (((((((((((( 17
sub ---- 18
main (((((((((((( 19
sub ---- 20
main (((((((((((( 21
sub ---- 22
main (((((((((((( 23
sub ---- 24
main (((((((((((( 25
sub ---- 26
main (((((((((((( 27
sub ---- 28
main (((((((((((( 29
sub ---- 30
main (((((((((((( 31
sub ---- 32
main (((((((((((( 33
sub ---- 34
main (((((((((((( 35
sub ---- 36
main (((((((((((( 37
理论上能打印到99,只到37,使用jstack看一下:
有很多线程wait
有两种解决方案:
1)改为notifyall,直接改,ok搞定
2)改为reetrantlock,使用两个condition
使用一个condition时,仍然要使用signalall,使用signal会死锁
使用2个condition的代码:
package multilock.deadlock; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * https://www.cnblogs.com/silyvin/p/11747303.html * Created by joyce on 2019/10/27. */ public class NotifyDeadLockRee { private boolean isSub = true; private int count = 0; private ReentrantLock lock = new ReentrantLock(); private Condition conditionSub = lock.newCondition(); private Condition conditionMain = lock.newCondition(); private Condition condition = lock.newCondition(); // dead with signall, signalAll ok public void sub() { try { lock.lock(); while (!isSub ) { conditionSub.await(); } System. out.println("sub ---- " + count); isSub = false ; conditionMain.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } count++; } public synchronized void main() { try { lock.lock(); while (isSub ) { conditionMain.await(); } System. out.println("main (((((((((((( " + count); isSub = true ; conditionSub.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } count++; } public static void main(String[] args) { // System.out.println("lock"); final NotifyDeadLockRee ot = new NotifyDeadLockRee(); for (int j = 0; j < 10; j++) { new Thread(new Runnable() { public void run() { for (int i = 0; i < 5; i++) { ot.sub(); } } }, "mysub").start(); new Thread(new Runnable() { public void run() { for (int i = 0; i < 5; i++) { ot.main(); } } }, "mymain").start(); } } }