wait和notify

new Thread(new Runnable() {
    @Override
    public void run() {
        long id = Thread.currentThread().getId();
        Log.i(TAG, "thread1 id :" + id + " begin");
        new Thread(new Runnable() {
            @Override
            public void run() {
                long id = Thread.currentThread().getId();
                Log.i(TAG, "thread2 id :" + id + " begin");
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.i(TAG, "thread2 id :" + id + " end before synchronized");
                synchronized (object){
                    Log.i(TAG, "thread2 id :" + id + " end before notify");
                    object.notify();
                    Log.i(TAG, "thread2 id :" + id + " end after notify");
                }
                Log.i(TAG, "thread2 id :" + id + " end after synchronized");
            }
        }).start();
        try {
            Log.i(TAG, "thread1 id :" + id + " before synchronized");
            synchronized (object){
                Log.i(TAG, "thread1 id :" + id + " before wait");
                object.wait();
                Log.i(TAG, "thread1 id :" + id + " after wait");
            }
            Log.i(TAG, "thread1 id :" + id + " after synchronized");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.i(TAG, "thread1 id :" + id + " end");
    }
}).start();
同时启动两个线程:

10-27 15:16:36.274  4751  4948 I wp20170906-MainActivity: thread1 id :1513 begin

10-27 15:16:36.277  4751  4948 I wp20170906-MainActivity: thread1 id :1513 before synchronized 
10-27 15:16:36.277  4751  4948 I wp20170906-MainActivity: thread1 id :1513 before wait 线程1513开始wait
10-27 15:16:36.277  4751  4949 I wp20170906-MainActivity: thread2 id :1514 begin 线程1514开始执行


10-27 15:16:37.128  4751  4950 I wp20170906-MainActivity: thread1 id :1515 begin
10-27 15:16:37.129  4751  4950 I wp20170906-MainActivity: thread1 id :1515 before synchronized
10-27 15:16:37.129  4751  4950 I wp20170906-MainActivity: thread1 id :1515 before wait 线程1515开始wait
10-27 15:16:37.129  4751  4951 I wp20170906-MainActivity: thread2 id :1516 begin 线程1516开始执行


10-27 15:16:39.278  4751  4949 I wp20170906-MainActivity: thread2 id :1514 end before synchronized 线程1514执行完毕
10-27 15:16:39.278  4751  4949 I wp20170906-MainActivity: thread2 id :1514 end before notify
10-27 15:16:39.278  4751  4949 I wp20170906-MainActivity: thread2 id :1514 end after notify 线程1514执行完毕,notify持有同一个锁的其他线程执行
10-27 15:16:39.278  4751  4949 I wp20170906-MainActivity: thread2 id :1514 end after synchronized
10-27 15:16:39.279  4751  4948 I wp20170906-MainActivity: thread1 id :1513 after wait 线程1513开始执行wait后面的逻辑
10-27 15:16:39.279  4751  4948 I wp20170906-MainActivity: thread1 id :1513 after synchronized
10-27 15:16:39.279  4751  4948 I wp20170906-MainActivity: thread1 id :1513 end 线程1513执行完毕


10-27 15:16:40.130  4751  4951 I wp20170906-MainActivity: thread2 id :1516 end before synchronized
10-27 15:16:40.130  4751  4951 I wp20170906-MainActivity: thread2 id :1516 end before notify
10-27 15:16:40.130  4751  4951 I wp20170906-MainActivity: thread2 id :1516 end after notify 线程1516执行完毕,notify持有同一个锁的其他线程执行
10-27 15:16:40.130  4751  4951 I wp20170906-MainActivity: thread2 id :1516 end after synchronized 
10-27 15:16:40.130  4751  4950 I wp20170906-MainActivity: thread1 id :1515 after wait 线程1515开始执行wait后面的逻辑
10-27 15:16:40.130  4751  4950 I wp20170906-MainActivity: thread1 id :1515 after synchronized
10-27 15:16:40.130  4751  4950 I wp20170906-MainActivity: thread1 id :1515 end 线程1515执行完毕

同时启动三个线程:

10-27 15:35:35.588  6892  7055 I wp20170906-MainActivity: thread1 id :1601 begin
10-27 15:35:35.590  6892  7055 I wp20170906-MainActivity: thread1 id :1601 before synchronized
10-27 15:35:35.590  6892  7055 I wp20170906-MainActivity: thread1 id :1601 before wait
10-27 15:35:35.590  6892  7056 I wp20170906-MainActivity: thread2 id :1602 begin


10-27 15:35:36.701  6892  7059 I wp20170906-MainActivity: thread1 id :1603 begin
10-27 15:35:36.703  6892  7059 I wp20170906-MainActivity: thread1 id :1603 before synchronized
10-27 15:35:36.703  6892  7059 I wp20170906-MainActivity: thread1 id :1603 before wait
10-27 15:35:36.704  6892  7060 I wp20170906-MainActivity: thread2 id :1604 begin


10-27 15:35:38.594  6892  7062 I wp20170906-MainActivity: thread1 id :1605 begin
10-27 15:35:38.595  6892  7062 I wp20170906-MainActivity: thread1 id :1605 before synchronized
10-27 15:35:38.595  6892  7062 I wp20170906-MainActivity: thread1 id :1605 before wait
10-27 15:35:38.598  6892  7063 I wp20170906-MainActivity: thread2 id :1606 begin
10-27 15:35:39.591  6892  7056 I wp20170906-MainActivity: thread2 id :1602 end before synchronized
10-27 15:35:39.591  6892  7056 I wp20170906-MainActivity: thread2 id :1602 end before notify
10-27 15:35:39.591  6892  7056 I wp20170906-MainActivity: thread2 id :1602 end after notify
10-27 15:35:39.591  6892  7056 I wp20170906-MainActivity: thread2 id :1602 end after synchronized
10-27 15:35:39.592  6892  7055 I wp20170906-MainActivity: thread1 id :1601 after wait
10-27 15:35:39.592  6892  7055 I wp20170906-MainActivity: thread1 id :1601 after synchronized
10-27 15:35:39.592  6892  7055 I wp20170906-MainActivity: thread1 id :1601 end


10-27 15:35:40.704  6892  7060 I wp20170906-MainActivity: thread2 id :1604 end before synchronized
10-27 15:35:40.704  6892  7060 I wp20170906-MainActivity: thread2 id :1604 end before notify
10-27 15:35:40.705  6892  7060 I wp20170906-MainActivity: thread2 id :1604 end after notify
10-27 15:35:40.705  6892  7060 I wp20170906-MainActivity: thread2 id :1604 end after synchronized
10-27 15:35:40.705  6892  7059 I wp20170906-MainActivity: thread1 id :1603 after wait
10-27 15:35:40.705  6892  7059 I wp20170906-MainActivity: thread1 id :1603 after synchronized
10-27 15:35:40.705  6892  7059 I wp20170906-MainActivity: thread1 id :1603 end


10-27 15:35:42.598  6892  7063 I wp20170906-MainActivity: thread2 id :1606 end before synchronized
10-27 15:35:42.598  6892  7063 I wp20170906-MainActivity: thread2 id :1606 end before notify
10-27 15:35:42.598  6892  7063 I wp20170906-MainActivity: thread2 id :1606 end after notify
10-27 15:35:42.598  6892  7063 I wp20170906-MainActivity: thread2 id :1606 end after synchronized
10-27 15:35:42.599  6892  7062 I wp20170906-MainActivity: thread1 id :1605 after wait
10-27 15:35:42.599  6892  7062 I wp20170906-MainActivity: thread1 id :1605 after synchronized
10-27 15:35:42.599  6892  7062 I wp20170906-MainActivity: thread1 id :1605 end

wait传入特定时间:

new Thread(new Runnable() {
    @Override
    public void run() {
        long id = Thread.currentThread().getId();
        Log.i(TAG, "thread1 id :" + id + " begin");
        new Thread(new Runnable() {
            @Override
            public void run() {
                long id = Thread.currentThread().getId();
                Log.i(TAG, "thread2 id :" + id + " begin");
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.i(TAG, "thread2 id :" + id + " end before synchronized");
                synchronized (object){
                    Log.i(TAG, "thread2 id :" + id + " end before notify");
                    object.notify();
                    Log.i(TAG, "thread2 id :" + id + " end after notify");
                }
                Log.i(TAG, "thread2 id :" + id + " end after synchronized");
            }
        }).start();
        try {
            Log.i(TAG, "thread1 id :" + id + " before synchronized");
            synchronized (object){
                Log.i(TAG, "thread1 id :" + id + " before wait");
                object.wait(2000);
                Log.i(TAG, "thread1 id :" + id + " after wait");
            }
            Log.i(TAG, "thread1 id :" + id + " after synchronized");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.i(TAG, "thread1 id :" + id + " end");
    }
}).start();

wait传入参数后
10-27 15:28:02.262  5907  6093 I wp20170906-MainActivity: thread1 id :1556 begin
10-27 15:28:02.264  5907  6093 I wp20170906-MainActivity: thread1 id :1556 before synchronized
10-27 15:28:02.264  5907  6093 I wp20170906-MainActivity: thread1 id :1556 before wait
10-27 15:28:02.266  5907  6094 I wp20170906-MainActivity: thread2 id :1557 begin
10-27 15:28:04.265  5907  6093 I wp20170906-MainActivity: thread1 id :1556 after wait
10-27 15:28:04.265  5907  6093 I wp20170906-MainActivity: thread1 id :1556 after synchronized
10-27 15:28:04.265  5907  6093 I wp20170906-MainActivity: thread1 id :1556 end
10-27 15:28:06.266  5907  6094 I wp20170906-MainActivity: thread2 id :1557 end before synchronized
10-27 15:28:06.266  5907  6094 I wp20170906-MainActivity: thread2 id :1557 end before notify
10-27 15:28:06.266  5907  6094 I wp20170906-MainActivity: thread2 id :1557 end after notify
10-27 15:28:06.266  5907  6094 I wp20170906-MainActivity: thread2 id :1557 end after synchronized
在Java多线程编程中,`wait()` `notify()` 是用于线程间通信的重要方法,它们定义在 `Object` 类中,并且必须在同步上下文中(如 `synchronized` 方法或代码块)中使用。这两个方法的主要作用是协调多个线程的执行顺序,确保线程之间可以安全地共享资源。 ### wait() 方法 `wait()` 方法的作用是使当前线程进入等待状态,直到其他线程调用该对象上的 `notify()` 或 `notifyAll()` 方法来唤醒它。调用 `wait()` 时,当前线程会释放持有的对象锁,并进入该对象的等待队列中[^4]。 一个典型的使用模式如下: ```java synchronized (lock) { while (!condition) { lock.wait(); } // 执行后续操作 } ``` 在此模式中,线程会在条件不满足时通过 `wait()` 进入等待状态,并在条件发生变化时被唤醒继续执行。 ### notify() 方法 `notify()` 方法用于唤醒在指定对象上等待的一个线程。如果有多个线程在等待,则由线程调度器随机选择其中一个进行唤醒。需要注意的是,调用 `notify()` 后,当前线程不会立即释放对象锁,而是要等到其所在的同步代码块或方法执行完毕后才会释放锁[^1]。 以下是一个简单的示例说明 `notify()` 的使用: ```java public class NotifyExample { public static void main(String[] args) { Object lock = new Object(); Thread t1 = new Thread(() -> { synchronized (lock) { System.out.println("t1 开始等待"); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t1 被唤醒"); } }); Thread t2 = new Thread(() -> { synchronized (lock) { System.out.println("t2 准备通知"); lock.notify(); System.out.println("t2 已通知"); } }); t1.start(); try { Thread.sleep(1000); // 确保 t1 先进入等待状态 } catch (InterruptedException e) { e.printStackTrace(); } t2.start(); } } ``` 在这个例子中,线程 `t1` 在进入同步代码块后调用 `wait()` 方法并释放锁,而线程 `t2` 在随后调用 `notify()` 来唤醒 `t1`。 ### 使用注意事项 - **必须在同步环境中使用**:`wait()` `notify()` 必须在 `synchronized` 方法或代码块中调用,否则会抛出 `IllegalMonitorStateException` 异常[^2]。 - **避免虚假唤醒**:通常建议将 `wait()` 放在一个循环中检查条件是否满足,以防止线程在没有收到通知的情况下被唤醒。 - **notify() 与 notifyAll() 的区别**:`notify()` 只唤醒一个等待线程,而 `notifyAll()` 唤醒所有等待线程,适用于需要处理多个线程竞争的情况[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值