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();
}
}
}