notifyAll(), notify()经常和wait()配合,进行多线程编程.
.wait:是一个线程睡眠,直到在相同的对象上调用notify或notifyAll
.notify:启动第一个在相同对象调用wait的线程
.notifyAll:启动在相同的对象调用wait的所有线程
如下代码:
其本意是调用十次线程.
代码:
public class Mymain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Mymain().test();
}
public void test(){
Manager manager = new Manager(4);
for(int i=0; i<10; i++){
System.out.println(i+":");
manager.PrintSync();
}
}
public class Manager {
int num;
public Manager(int num){
this.num = num;
player = new Player[num];
for(int i=0; i<num; i++){
player[i] = new Player();
player[i].setid(i);
player[i].setManager(this);
}
}
Player player[];
public void PrintSync(){
for(int i=0; i<num; i++){
if (player[i].free){
System.out.println("use thread "+i);
player[i].free = false;
new Thread(player[i]).start();
return;
}
}
System.out.println("all busy!");
}
}
public class Player implements Runnable{
Manager manager;
public void setManager(Manager manager){
this.manager = manager;
}
int id;
public void setid(int id){
this.id = id;
}
public boolean free = true;
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread "+ id + " is end!");
free = true;
}
}
}
结果:
0:
use thread 0
1:
use thread 1
2:
use thread 2
3:
use thread 3
4:
all busy!
5:
all busy!
6:
all busy!
7:
all busy!
8:
all busy!
9:
all busy!
Thread 0 is end!
Thread 1 is end!
Thread 2 is end!
Thread 3 is end!
观察结果,由于只创建了四个线程,从而线程只调用了四次.
改进方法:
加入wait()方法,当查看到线程都在使用的时候,进行阻塞.
代码:
public class Manager {
…
public void PrintSync(){
CheckFree();
for(int i=0; i<num; i++){
if (player[i].free){
System.out.println("use thread "+i);
player[i].free = false;
new Thread(player[i]).start();
return;
}
}
}
public void CheckFree(){
for(int i=0; i<num; i++){
if (player[i].free){
return;
}
}
synchronized(this){
try {
System.out.println("wait()!");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
运行结果:
0:
use thread 0
1:
use thread 1
2:
use thread 2
3:
use thread 3
4:
wait()!
Thread 0 is end!
Thread 1 is end!
Thread 2 is end!
Thread 3 is end!
观察结果,进行了阻塞,但是由于没有唤醒,所以一直阻塞,因此加入notifyAll()方法.
代码:
public class Manager {
…
public void Noti(){
synchronized(this){
notifyAll();
}
}
}
public class Player implements Runnable{
…
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread "+ id + " is end!");
free = true;
manager.Noti();
}
}
运行结果:
0:
use thread 0
1:
use thread 1
2:
use thread 2
3:
use thread 3
4:
wait()!
Thread 0 is end!
use thread 0
5:
wait()!
Thread 1 is end!
use thread 1
6:
wait()!
Thread 2 is end!
use thread 2
7:
wait()!
Thread 3 is end!
use thread 3
8:
wait()!
Thread 0 is end!
use thread 0
9:
wait()!
Thread 1 is end!
use thread 1
Thread 2 is end!
Thread 3 is end!
Thread 0 is end!
Thread 1 is end!
由此可见:
.wait:是一个线程睡眠,直到在相同的对象上调用notify或notifyAll
.notify:启动第一个在相同对象调用wait的线程
.notifyAll:启动在相同的对象调用wait的所有线程