3.1等待/通知机制(wait/notify)

wait/notify

要点wait()
执行前在调用wait()之前,必须先要获得对象锁,即只有在同步方法或者同步代码块中调用wait()方法。
执行作用wait()使进程进入等待(阻塞状态),在收到通知或者被中断之前都会进入预执行队列。
执行之后1执行wait()之后,当前线程释放改对象锁,在通知前与其他线程重新竞争资源
执行之后2执行wait()之后,如果没有使用notify()通知其他线程,即使该对象资源空闲,其他使用过wait()线程由于没有通知会继续阻塞直到这个对象发出notify或者notifyAll
/wait()是Object对象的方法。

要点notify()
执行前在调用notify()之前,必须先要获得对象锁,即只有在同步方法或者同步代码块中调用notify()方法。
执行作用通知一个等待该对象资源的线程进入就绪状态,如果有多个线程等待,怎有线程规划器来挑选一个进入就绪状态(区别notify和notifyAll
执行之后执行notify之后,当前线程并不会立即释放锁,只有当执行完sychronized方法或者代码块的时候,当前线程才会释放锁
/notify()是Object对象的方法。

wait()之后锁立即释放和notify()之后锁不立即释放

针对上面的锁释放不释放,来做一个小的例子

先做wait()之后锁立即释放

package com.myObject;

public class Object1 {

    public void mothd1(Object lock) {
        synchronized (lock) {
            try {
                System.out.println("wait begin");
                lock.wait();
                System.out.println("wait end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
package com.myThread;

import com.myObject.Object1;

public class Thread1a extends Thread {
    Object lock;
    Object1 object1 = new Object1();

    public Thread1a(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        object1.mothd1(lock);
    }
}
package com.myThread;

import com.myObject.Object1;

public class Thread1b extends Thread {
    Object lock;
    Object1 object1 = new Object1();

    public Thread1b(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        object1.mothd1(lock);
    }
}
package com.test;

import com.myThread.Thread1a;
import com.myThread.Thread1b;

public class Test1 {
    public static void main(String[] args){
        Object lock = new Object();
        Thread1a thread1a = new Thread1a(lock);
        thread1a.start();
        Thread1b thread1b = new Thread1b(lock);
        thread1b.start();

    }
}

打印结果

wait begin
wait begin

下面是验证notify()之后锁不立即释放

package com.myObject;

public class Object1 {

    public void mothd1(Object lock) {
        synchronized (lock) {
            try {
                System.out.println(Thread.currentThread().getName()+" wait begin " + System.currentTimeMillis());
                lock.wait();
                System.out.println(Thread.currentThread().getName()+" wait end " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    public void mothd2(Object lock) {
        synchronized (lock) {
            try {
                System.out.println(Thread.currentThread().getName()+"notify begin " + System.currentTimeMillis());
                lock.notify();
                Thread.sleep(5000);//延时用于测试是否有立即释放锁
                System.out.println(Thread.currentThread().getName()+"notify end " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
package com.myThread;

import com.myObject.Object1;

public class Thread1a extends Thread {
    Object lock;
    Object1 object1 = new Object1();

    public Thread1a(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        object1.mothd1(lock);
    }
}
package com.myThread;

import com.myObject.Object1;

public class Thread1b extends Thread {
    Object lock;
    Object1 object1 = new Object1();

    public Thread1b(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        object1.mothd2(lock);
    }
}
package com.test;

import com.myThread.Thread1a;
import com.myThread.Thread1b;

public class Test1 {
    public static void main(String[] args) throws InterruptedException{
        Object lock = new Object();
        Thread1a thread1a = new Thread1a(lock);
        thread1a.setName("A");
        thread1a.start();
        Thread.sleep(1000);
        Thread1b thread1b = new Thread1b(lock);
        thread1b.setName("B");
        thread1b.start();

    }
}

打印结果

A wait begin 1453090470087
Bnotify begin 1453090471088
Bnotify end 1453090476088
A wait end 1453090476088

说明notify必须在执行完synchronized同步方法或者同步代码块之后才释放锁

wait之后使用interrupt

package com.myObject;

public class Object2 {

    public void mothd1(Object lock) {
        synchronized (lock) {
            try {
                System.out.println(Thread.currentThread().getName()+" wait begin " + System.currentTimeMillis());
                lock.wait();
                System.out.println(Thread.currentThread().getName()+" wait end " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }


}
package com.myThread;

import com.myObject.Object2;

public class Thread2 extends Thread {
    Object lock;
    Object2 object2 = new Object2();

    public Thread2(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        object2.mothd1(lock);
    }
}

package com.test;

import com.myThread.Thread2;

public class Test2 {
    public static void main(String[] args) throws InterruptedException{
        Object lock = new Object();
        Thread2 thread2 = new Thread2(lock);
        thread2.setName("A");
        thread2.start();
        Thread.sleep(1000);
        thread2.interrupt();

    }
}

当线程处于wait()时,调用线程对象的interrupt()会出现InterruptedException

总结:释放锁的时刻有
1)同步代码完成
2)抛出异常或者return
3)wait()方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值