Condition的signal()和Synchronized的notiy()的区别,一文弄懂!

13 篇文章 0 订阅

Condition的signal()和Synchronized的notiy()的区别,一文弄懂!

  1. Condition中的 await() 方法相当于 Object 的 wait() 方法,Condition中的 signal() 方法相当于Object的notify()方法,Condition中的 signalAll() 相当于Object的notifyAll()方法。不同的是,Object中的这些方法是和同步锁捆绑使用的;而Condition是需要与互斥锁/共享锁捆绑使用的。

  2. Condition它更强大的地方在于:能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition。

  3. 注意:当方法wait()被执行后,锁自动被释放,但执行完notify()方法后,锁不会自动释放。必须执行完notify()方法所在的synchronized代码块后才释放。

    那么Notify为什么不能精细控制呢,notify由于是随机唤醒,可能会导致一种情况,即所有线程都被堵塞了,没有哪个线程再去执行notify唤醒。看如下代码:

public class ConditionTest {
    //共享变量 标志位 A = 1 B = 2 C = 3
    int count = 1;
    public static void main(String[] args) {
        ConditionTest conditionTest = new ConditionTest();
        for (int i = 0 ; i < 10 ;i++) {
            new Thread(() -> {
                try {
                    conditionTest.printA();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "A").start();

            new Thread(() -> {
                try {

                    conditionTest.printB();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "B").start();

            new Thread(() -> {
                try {
                    conditionTest.printC();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "C").start();
        }
    }
    public synchronized void printA() throws InterruptedException {
        while (count != 1){
            System.out.println(Thread.currentThread().getName()+"不该此线程操作等待中...");
            this.wait();
        }
        for (int i = 1; i <6 ; i++) {
            System.out.println(Thread.currentThread().getName()+"打印"+i);
        }
        count = 2;
        this.notify();
    }
    public synchronized void printB() throws InterruptedException {
        while (count != 2){
            System.out.println(Thread.currentThread().getName()+"不该此线程操作等待中...");
            this.wait();
        }
        for (int i = 6; i <11 ; i++) {
            System.out.println(Thread.currentThread().getName()+"打印"+i);
        }
        count = 3;
        this.notify();

    }
    public synchronized void printC() throws InterruptedException {
        while (count != 3){
            System.out.println(Thread.currentThread().getName()+"不该此线程操作等待中...");
            this.wait();
        }
        for (int i = 11; i <16 ; i++) {
            System.out.println(Thread.currentThread().getName()+"打印"+i);
        }
        count = 1;
        this.notify();

    }
}
A打印1
A打印2
A打印3
A打印4
A打印5				//A执行到这里后实现notify()
A不该此线程操作等待中... //不满足while条件A堵塞
C不该此线程操作等待中... //不满足while条件 此时A和C在堵塞队列中
B打印6
B打印7
B打印8
B打印9
B打印10				//B执行notify(),正好B不满足while条件,堵塞
B不该此线程操作等待中... //B执行的notify随机唤醒了A线程
A不该此线程操作等待中... //A线程不满足条件堵塞中,现在ABC都堵塞了,没人再去执行notify()
//进入..死循环
public class ConditionTest {
    //共享变量 标志位 A = 1 B = 2 C = 3
    int count = 1;
    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();

    public static void main(String[] args) {
        ConditionTest conditionTest = new ConditionTest();
        new Thread(() -> {
            try {
                for (int i = 0 ;i < 10 ; i++)
                conditionTest.printA();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();

        new Thread(() -> {
            try {
                for (int i = 0 ;i < 10 ; i++)

                conditionTest.printB();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "B").start();

        new Thread(() -> {
            try {
                for (int i = 0 ;i < 10 ; i++)

                    conditionTest.printC();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "C").start();
    }

    public  void printA() throws InterruptedException {
        lock.lock();
        try {
            while (count != 1){
                System.out.println(Thread.currentThread().getName()+"不该此线程操作等待中...");
                condition1.await();
            }
            for (int i = 1; i <6 ; i++) {
                System.out.println(Thread.currentThread().getName()+"打印"+i);
            }
            count = 2;
            condition2.signal();
        } finally {
            lock.unlock();
        }
    }
    public  void printB() throws InterruptedException {
        lock.lock();
        try {
            while (count != 2){
                System.out.println(Thread.currentThread().getName()+"不该此线程操作等待中...");
                condition2.await();
            }
            for (int i = 6; i <11 ; i++) {
                System.out.println(Thread.currentThread().getName()+"打印"+i);
            }
            count = 3;
            condition3.signal();
        } finally {
            lock.unlock();
        }
    }
    public  void printC() throws InterruptedException {
        lock.lock();
        try {
            while (count != 3){
                System.out.println(Thread.currentThread().getName()+"不该此线程操作等待中...");
                condition3.await();
            }
            for (int i = 11; i <16 ; i++) {
                System.out.println(Thread.currentThread().getName()+"打印"+i);
            }
            count = 1;
            condition1.signal();
        } finally {
            lock.unlock();
        }
    }

通过condition1 ,2,3 进行精确唤醒。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值