有效解决线程之间的通信的两种手段:
1.wait()方法
2.notify()方法
如果一个正在执行同步代码(synchronized)的线程A执行wait()调用,则暂停执行并且排到一个等待的队列,同时释放已经获得的互斥锁。直到其他线程调用notify()或者notifyAll()方法,才能重新获得互斥锁。
notify()的作用就是用来唤醒正在等待互斥锁的第一个线程。
notifyAll()的作用是用来唤醒所有的在队列中的线程,并且具有最高优先级的线程获得互斥锁。
注意:wait()和notify()只能在同步代码块中调用。
使线程阻塞的两种方法:sleep(),wait()。
sleep和wait的区别:
wait()放弃CPU资源的同时也交出了资源的控制权,而sleep()只交出了CPU资源。
代码演示:两个线程模拟存取票,要求没存入一张票,就售出一张票。知道售完为止
package practice4;
public class Tickets {
protected int size;
int number=0;
boolean available=false;
public Tickets(int size){
this.size=size;
}
public synchronized void put(){
//存票
if(available){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("存入第【"+(++number)+"】号票");
available=true;
notify();//唤醒售票系统开始售票
}
public synchronized void sell(){
//售票
if(!available){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("售出第【"+number+"】号票");
available=false;
notify();//唤醒存票线程开始存票
if(number==size) number=size+1;
}
}
public class Producer extends Thread{
Tickets t=null;
public Producer(Tickets t){
this.t=t;
}
public void run(){
while(t.number<t.size)
t.put();
}
}
public class Consumer extends Thread{
Tickets t=null;
public Consumer(Tickets t){
this.t=t;
}
public void run(){
while(t.number<=t.size){
t.sell();
}
}
}
public class App11_8 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Tickets t=new Tickets(10);
new Producer(t).start();
new Consumer(t).start();
}
}