[JAVAee]多线程-wait方法与notify方法

我们知道,线程之间是抢占式执行的.通俗来说,就是随机调度的.每一个线程什么时候运行我们也不知道.

这里就来介绍,让线程可以按照一定顺序执行的方法.

目录

1.wait方法

2.notify \ notifyAll方法

3.使用wait与notify的注意事项

①wait与notify都为Object类的类方法

②搭配synchronized关键字使用

③使用示例


1.wait方法

方法 说明
wait() 导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法

wait(long timeout)

导致当前线程等待,直到另一个线程调用notify()方法或该对象的 notifyAll方法,或者指定的时间已过

wait方法主要是让线程进入阻塞的状态,使其不能往下执行.

wait方法要搭配synchronized关键字,即锁来使用.

其还是一个object类方法,建议新创建一个object类单独搭配使用.

经过为:

  • 使调用了这个方法的线程进入阻塞状态(进入等待队列中).
  • 释放当前的锁.
  • 等待别的线程调用notify方法将其唤醒,再重新获取此锁.

2.notify \ notifyAll方法

方法 说明
notify() 唤醒正在等待对象监视器的单个线程
notifyAll() 唤醒正在等待对象监视器的所有线程

(为了方便,除了特别说明.下文notify与notifyAll方法统称为notify方法) 

notify\notifyAll方法,同样的搭配synchronized关键字来使用.

同样的也是object类方法.

唤醒在其他线程中调用notify方法,唤醒调用了同一个object类对象wait方法的线程.

经过为:

(背景: 此处的wait与notify方法在同一个类对象当中.且线程A调用了wait方法)

  • 线程B调用了notify方法,发出了notify通知,通知线程A重新获取此object类对象的锁
  • 使等待队列中的线程A得到唤醒.如果等待队列中有多个线程,则随机将其一唤醒.
  • 线程B中执行完锁中的内容,使锁得到释放
  • 此时线程A可以获取锁,可以执行下面的内容

3.使用wait与notify的注意事项

①wait与notify都为Object类的类方法

在与wait方法同一个object对象的notify方法才能将其唤醒

Object object = new Object();
        object.wait();
        object.notify();

②搭配synchronized关键字使用

使用synchronized关键字的理由,因为搭配使用的wait与notify方法放在同一个类对象中.

我们的期望是线程A在满足一定的条件下才调用wait方法,线程B又要判断一定的条件才去调用notify方法唤醒线程A.

但因为线程是抢占式的执行,对于哪一个线程先执行是随机的.

如果没有在synchronized修饰的代码块下:

  • 线程A在判断条件决定要去执行wait方法但还没去来得及使用wait方法后.
  • 这时调度到了线程B,线程B看到线程A没有进入阻塞状态认为其还没有达到wait的条件而去进行了其他的操作.
  • 当又调度到了线程A的时候,这时线程A又进入到了阻塞的状态.

 这显然不是我们期望看到的结果,如果使用了synchronized对其上锁.就不会发生这种多线程环境下的执行问题

③使用示例

public static void main(String[] args) throws InterruptedException {
        Object object = new Object();
        //代码中的对象1,2,3,4是要同一个对象才能相应的有正确的效果.
        // 如果四个对象任一不相同的话就会导致错误
        Thread thread0 = new Thread(() -> {
           synchronized (object){//此处的对象①
               System.out.println("wait之前");
               try {
                   object.wait();//此处的对象②
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               System.out.println("wait之后");
           }
        });

        Thread thread1 = new Thread(() ->{
           synchronized (object){//此处的对象③
               System.out.println("notift之前");
               object.notify();//此处的对象④
               System.out.println("notify之后");
           }
        });
        thread0.start();
        Thread.sleep(1000);
        thread1.start();

    }

猜你喜欢

转载自blog.csdn.net/weixin_67719939/article/details/131871758
今日推荐