java源码——Object的wait(),notify(),notifyAll()

本文详细解释了Java中wait(),wait(longtimeout),notify(),和notifyAll()方法的作用、使用场景和示例,展示了它们在多线程同步中的关键作用,特别是如何实现线程间的协作与唤醒。

目录

1.wait()和wait(long timeout)

1.wait的作用

2.示例说明

2.notify()

3.notifyAll()


1.wait()和wait(long timeout)

1.wait的作用

1.使当前执行代码的线程进行等待。(把线程放在等待队列中)
2.释放当前锁(这需要调用wait的线程是加锁状态,这里的释放是指先暂停对Synchronized所修饰的代码块的   运行,后续在重新获取锁的占有权后继续执行wait代码后面的部分)。
3.满足一定条件时,让使用wait的线程被唤醒(其他线程中调用notify/notifyAll,或者代码抛出
  InterruptedException,线程宕掉等),需要重新获取这个锁(需要参与锁竞争)。

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

wati(0)的作用是释放锁,并一直休眠

wait(1000)的作用是释放锁,1000ms后重新竞争锁

2.示例说明

package com.source.object;

/**
 * @author dongguanghui
 * @date 2024/1/19 16:05
 */
public class Wait1 {
    public static void main(String[] args) {
        Object object = new Object();
        Thread thread0 = new Thread(() -> {
            synchronized (object) {
                System.out.println("0抢到锁");
                try {
                    System.out.println("0释放锁");
                    object.wait(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("0执行完");
            }
        });

        Thread thread1 = new Thread(() -> {
            synchronized (object) {
                System.out.println("1抢到锁");
                try {
                    Thread.sleep(2000);
                    System.out.println("1释放锁");
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("1执行完");
            }
        });

        thread0.start();
        thread1.start();

    }
}

以上代码有两种可能的结果

1.thread0先抢到锁

0释放锁后,等待3秒后再去抢锁,继续执行直到完成

1抢到锁后,2秒后释放锁,一直休眠

0抢到锁
0释放锁
1抢到锁
1释放锁
0执行完

2.thread1先抢到锁

1抢到锁后,2秒后释放锁,一直休眠

0抢到锁后,释放锁,等待3秒后再去抢锁,继续执行直到完成

1抢到锁
1释放锁
0抢到锁
0释放锁
0执行完

2.notify()

notify()表示随机唤醒一个休眠中的锁

package com.source.object;

/**
 * @author dongguanghui
 * @date 2024/1/19 16:53
 */
public class Wait2 {
    public static void main(String[] args) {
        Object object = new Object();
        Thread thread0 = new Thread(() -> {
            synchronized (object) {
                System.out.println("0抢到锁");
                try {
                    System.out.println("0释放锁");
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("0执行完");
            }
        });

        Thread thread1 = new Thread(() -> {
            synchronized (object) {
                System.out.println("1抢到锁");
                try {
                    System.out.println("1释放锁");
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("1执行完");
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (object) {
                object.notify();
                System.out.println("唤醒完成");
            }
        });

        thread0.start();
        thread1.start();
        thread2.start();

    }
}

以上代码有两种结果

1.唤醒0

0抢到锁
0释放锁
1抢到锁
1释放锁
唤醒完成

0执行完

2.唤醒1

1抢到锁
1释放锁
0抢到锁
0释放锁
唤醒完成
1执行完

3.notifyAll()

notifyAll() 方法是用来唤醒当前对象的所有调用 wait() 的线程.

package com.source.object;

/**
 * @author dongguanghui
 * @date 2024/1/19 16:53
 */
public class Wait3 {
    public static void main(String[] args) {
        Object object = new Object();
        Thread thread0 = new Thread(() -> {
            synchronized (object) {
                System.out.println("0抢到锁");
                try {
                    System.out.println("0释放锁");
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("0执行完");
            }
        });

        Thread thread1 = new Thread(() -> {
            synchronized (object) {
                System.out.println("1抢到锁");
                try {
                    System.out.println("1释放锁");
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("1执行完");
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (object) {
                object.notifyAll();
                System.out.println("唤醒完成");
            }
        });

        thread0.start();
        thread1.start();
        thread2.start();

    }
}

执行结果有两种情况,取决于唤醒之后,谁先抢到锁

1.1先抢到

0抢到锁
0释放锁
1抢到锁
1释放锁
唤醒完成
1执行完
0执行完

2.0先抢到

1抢到锁
1释放锁
0抢到锁
0释放锁
唤醒完成
0执行完
1执行完

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值