在java中加了synchronized(lock)中,调用lock.wait和直接调用wait的区别?

synchronized(lock)中确定了,当前线程执行这段同步代码块,必须获取lock的对象锁(也就是判断lock对象的加锁计数器的值是否为零,为零则获取并将加锁计数器的值加1,不为零等待)。

在代码块中执行lock.wait()方法,该线程放弃lock对象锁(也就是lock维护的加锁计数器的值减1),等待其他线程执行notifyAll()或者notify()方法可能将它唤醒…,还有很多不细说了。

notify()或notifyAll()方法调用后,等待线程依旧不会从wait()返回,需要调用notify()或 notifAll()的线程释放锁之后,等待线程才有机会从wait()返回。

直接执行wait(),会报异常。如果这一同步代码所在方法是实例方法那就是实例的this.wait()方法 ,如果是类方法,那就执行Class对象的wait()方法。 很明显,该线程并没有获取到这两个对象的对象锁,而执行wait()方法的前提就是当前线程获取了对象的对象锁,所以会报异常。

代码示例:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class WaitNotify {
    static boolean flag = true;
    static Object lock = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread waitThread = new Thread(new Wait(),"WaitThread");
        waitThread.start();
        TimeUnit.SECONDS.sleep(1);
        Thread notifyThread = new Thread(new Notify(),"NotifyThread");
        notifyThread.start();
    }
    static class Wait implements Runnable{
        public void run(){
            // 加锁,拥有lock的Monitor
            synchronized (lock){
                // 当条件不满足时,继续wait,同时释放了lock的锁
                while(flag){
                    try {
                        System.out.println(String.format(Thread.currentThread() + " flag is true. wait@ " + new SimpleDateFormat("HH:mm:ss").format(new Date())));
                        lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println(Thread.currentThread() + " flag is false. running@ "+new SimpleDateFormat("HH:mm:ss").format(new Date()));
            }
        }
    }

    static class Notify implements Runnable{

        @Override
        public void run() {
            // 加锁,拥有lock的Monitor
            synchronized (lock){
                // 获取lock的锁,然后进行通知,通知时不会释放锁,
                // 直到当前线程释放lock后,WaitThread 才能从wait方法中返回
                System.out.println(Thread.currentThread() + " hold lock. notify@ "+new SimpleDateFormat("HH:mm:ss").format(new Date()));
                lock.notifyAll();
                flag = false;

            }
            synchronized (lock){
                System.out.println(Thread.currentThread() + "hold lock again. sleep@ " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
           
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值