四、wait-notify

wait-notify必须配合synchronized,并且为重量级锁。

await-signal必须配合lock

目录

图解monitor原理

wait()和wait(long timeoutMillis)

notify() 和notifyAll() 

wait()和sleep()


图解monitor原理

在Java中,每个对象都有一个内置的锁,也称为监视器锁(monitor)。当一个线程试图进入一个同步块(synchronized block)时,它需要首先获取该对象的监视器锁。如果锁已经被其他线程持有,那么试图获取锁的线程将被阻塞,直到锁被释放。

在monitor中有一个owner和两个队列。其中owner指的是当前拥有锁的线程,而两个队列分别为:

1、同步队列:用于存放等待获取对象锁的线程。当对象的锁被释放时,同步队列中的线程会被唤醒并尝试获取锁。

2、等待队列:用于存放调用了对象的wait()方法的线程。当其他线程调用了对象的notify()或notifyAll()方法时,等待队列中的线程会被唤醒并移动到同步队列中,等待获取对象的锁。

wait()和wait(long timeoutMillis)

在Java中,wait()方法是Object类的一个方法,用于让当前线程进入等待状态。wait()方法也会让当前线程释放它所持有的该对象的锁,以使其他线程可以获取该锁并执行同步代码块。

在Object类中,有两个关于wait的方法:一个是wait() ,另一个是wait(long timeoutMillis)。而wait()方法实际上就是调用了wait(0):

public final void wait() throws InterruptedException {
        wait(0L);
}

wait(long timeoutMillis)方法,它会让当前线程等待指定的时间(以毫秒为单位)。如果在这段时间内,其他线程调用了同一对象的notify()或notifyAll()方法,那么当前线程会被唤醒并尝试重新获取锁。如果在这段时间内没有其他线程调用这些方法,那么当前线程会在等待时间结束后自动被唤醒。需要注意的是,即使等待时间结束,也并不意味着当前线程可以立即获取锁并继续执行。如果有其他线程正在持有锁,那么当前线程仍然需要等待锁被释放。

notify() 和notifyAll() 

在Java中,notify()和notifyAll()是Object类的两个方法,用于唤醒在该对象上等待的线程。这两个方法必须在同步块或同步方法中调用,也就是当前线程必须持有该对象的锁。  

notify()方法:会随机唤醒在该对象上等待的一个线程。如果有多个线程在等待,它只会选择其中一个线程并将其唤醒。  

notifyAll()方法:会唤醒在该对象上等待的所有线程。所有被唤醒的线程将会竞争重新获取锁,然后继续执行。

public class MyRunnable implements Runnable {
    private Object lock = new Object();

    public void doNotify() {
        synchronized (lock) {
            lock.notify(); //唤醒等待队列中的一个线程
        }
    }

    public void doNotifyAll() {
        synchronized (lock) {
            lock.notifyAll();//唤醒等待队列中的所有线程
        }
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                lock.wait(); //当前线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 当前线程被唤醒后会继续从这里执行
        }
    }
}

wait()和sleep()

在Java中,wait()和sleep()都可以让当前线程暂停执行,但它们的用途和行为有一些重要的区别: 1. 来源不同:wait()是Object类的方法,而sleep()是Thread类的静态方法。  

2. 锁的释放:当线程执行wait()方法时,它会释放它所持有的该对象的锁,这使得其他线程可以获取该锁并执行同步代码块。而当线程执行sleep()方法时,它不会释放任何锁。  

3. 唤醒方式:wait()方法可以通过notify()或notifyAll()方法来唤醒等待的线程。而sleep()方法则在指定的时间过后自动唤醒,或者可以通过interrupt()方法来中断线程的睡眠。  

4. 使用场景:wait()、notify()和notifyAll()方法通常用于多个线程间的协调和通信,比如生产者/消费者模型。而sleep()方法通常用于让当前线程暂停一段时间,比如模拟耗时操作或者控制线程的执行速度。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值