码迷,mamicode.com
首页 > 其他好文 > 详细

notify 与 nofityall,notify造成死锁实践

时间:2019-10-27 14:46:00      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:try   syn   打印   sub()   create   new t   直接   created   dead   


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

 

notify 与 nofityall,notify造成死锁实践

标签:try   syn   打印   sub()   create   new t   直接   created   dead   

原文地址:https://www.cnblogs.com/silyvin/p/11747303.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!