Java中wait,notify和notifyAll方法示例

您可能已经注意到Object类具有三个最终方法,分别称为wait,notify和notifyAll。这些方法用于线程间通信。Java 5引入了执行程序框架,该执行程序框架为您处理线程间通信,并在内部使用wait,notify和notifyAll。但是您仍然需要对这些方法以及线程间通信如何在Java中使用wait,notify和notifyAll进行基本了解。

什么是wait,notify和notifyAll方法?

wait,notify和notifyAll方法用于允许线程通过访问公共对象彼此通信,或者换句话说,对象可以被视为通过这些方法进行线程间通信的媒介。这些方法需要从同步上下文中调用,否则将抛出java.lang.IllegalMonitorStateException。

同步块的一些背景:

  • 同步块中一次只能进入一个线程
  • 线程需要锁定对象才能进入同步块。
  • 如果线程A要进入同步块,则线程A必须等待线程B释放它。
让我们对这些方法有一些简要的了解:

wait():

当您在对象上调用wait方法时,它告诉线程放弃锁并进入睡眠状态,除非并且直到其他线程进入同一监视器并在其上调用notify或notifyAll方法。

notify():

当您在对象上调用notify方法时,它将唤醒等待该对象的线程之一。因此,如果有多个线程在等待一个对象,它将唤醒其中之一。现在,您一定想知道它将唤醒哪一个。它实际上取决于OS的实现。

notifyAll():

notifyAll会唤醒所有在该对象上等待的线程,而不是notify会只唤醒其中一个线程,哪个线程会首先唤醒取决于线程优先级和操作系统实现。

让我们借助示例了解它:

1.创建一个名为Book.java的类:

这是Java bean类,线程将在该Java bean类上作用并调用wait和notify方法。

 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
package org.arpit.java2blog.thread;
 
public class Book {
 
String title;
boolean isCompleted;
 
public Book(String title) {
  super();
  this.title = title;
}
 
public String getTitle() {
  return title;
}
public void setTitle(String title) {
  this.title = title;
}
public boolean isCompleted() {
  return isCompleted;
}
public void setCompleted(boolean isCompleted) {
  this.isCompleted = isCompleted;
}
 
}
 

2.创建一个名为BookReader.java的类

该线程将等到其他线程调用notify方法,然后再完成其处理。它将首先锁定书本对象,然后从同步块中调用它。因此在本示例中,它将等待BookWriter完成书本。

 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
package org.arpit.java2blog.thread;
 
public class BookReader implements Runnable{
 
Book book;
 
public BookReader(Book book) {
  super();
  this.book = book;
}
 
@Override
public void run() {
  synchronized (book) {
   System.out.println(Thread.currentThread().getName()+" is waiting for the book to be completed: "+book.getTitle());
   try {
    book.wait();
   } catch (InterruptedException e) {    
    e.printStackTrace();
   }
   System.out.println(Thread.currentThread().getName()+": Book has been completed now!! you can read it");
  }
}
 
}
 

3.创建一个名为BookWriter.java的类

此类将通知正在等待书本对象的线程(如果有notify的话)。一旦调用notify,它将不会放弃锁,它首先完成其同步块。因此,在此示例中,BookWriter将完成书籍并将其通知给BookReaders。
 

 

 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
package org.arpit.java2blog.thread;
public class BookWriter implements Runnable{
 
Book book;
 
public BookWriter(Book book) {
  super();
  this.book = book;
}
 
@Override
public void run() {
  synchronized (book) {
   System.out.println("Author is Starting book : " +book.getTitle() );
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   book.setCompleted(true);
   System.out.println("Book has been completed now");
 
   book.notify();
   System.out.println("notify one reader");
 
  }
}
}
 

4.创建一个类ThreadInterCommunicationMain,java。

这是我们的主类,它将创建上述类的对象并运行它。

 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
package org.arpit.java2blog.thread;
 
public class ThreadInterCommunicationMain {
 
public static void main(String args[])
{
  // Book object on which wait and notify method will be called
  Book book=new Book("The Alchemist");
  BookReader johnReader=new BookReader(book);
  BookReader arpitReader=new BookReader(book);
 
  // BookReader threads which will wait for completion of book
  Thread johnThread=new Thread(johnReader,"John");
  Thread arpitThread=new Thread(arpitReader,"Arpit");
 
  arpitThread.start();
  johnThread.start();
 
  // To ensure both readers started waiting for the book
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
 
   e.printStackTrace();
  }
  // BookWriter thread which will notify once book get completed
  BookWriter bookWriter=new BookWriter(book);
  Thread bookWriterThread=new Thread(bookWriter);
  bookWriterThread.start();
 
}
 
}
 

在notify()的情况下:

当您运行上述程序时,将得到以下输出:

 
 
 
 
1
2
3
4
5
6
7
8
 
Arpit is waiting for the book to be completed: The Alchemist
John is waiting for the book to be completed: The Alchemist
Author is Starting book : The Alchemist
Book has been completed now
notify one reader
Arpit: Book has been completed now!! you can read it
 

 

如果是notifyAll():可以

将BookWriter类更改为调用book.notifyAll()。

 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
package org.arpit.java2blog.thread;
 
public class BookWriter implements Runnable{
 
Book book;
 
public BookWriter(Book book) {
  super();
  this.book = book;
}
 
@Override
public void run() {
  synchronized (book) {
   System.out.println("Author is Starting book : " +book.getTitle() );
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   book.setCompleted(true);
   System.out.println("Book has been completed now");
 
   book.notifyAll();
   System.out.println("notify readers");
 
  }
}
 
}
 

当您运行上述程序时,将得到以下输出:

 
1
2
3
4
5
6
7
8
9
 
Arpit is waiting for the book to be completed: The Alchemist
John is waiting for the book to be completed: The Alchemist
Author is Starting book : The Alchemist
Book has been completed now
notify readers
John: Book has been completed now!! you can read it
Arpit: Book has been completed now!! you can read it
 

如果是notifyAll(),它将通知所有正在等待该对象的线程。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值