您可能已经注意到Object类具有三个最终方法,分别称为wait,notify和notifyAll。这些方法用于线程间通信。Java 5引入了执行程序框架,该执行程序框架为您处理线程间通信,并在内部使用wait,notify和notifyAll。但是您仍然需要对这些方法以及线程间通信如何在Java中使用wait,notify和notifyAll进行基本了解。
什么是wait,notify和notifyAll方法?
同步块的一些背景:
- 同步块中一次只能进入一个线程
- 线程需要锁定对象才能进入同步块。
- 如果线程A要进入同步块,则线程A必须等待线程B释放它。
wait():
notify():
notifyAll():
让我们借助示例了解它:
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的类
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(),它将通知所有正在等待该对象的线程。