线程的通信
涉及到的三个方法:
(1)wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器
(2)notify():一旦执行此方法,就会唤醒被wait的一个线程,如果有多个线程被wait,就唤醒优先级高的那个
(3)notifyAll():一旦执行此方法,就会唤醒被wait的所有线程
说明:
(1)wait(),notify(,notifyAll()三个方法必须使用在同步代码块或同步方法中
(2)wait(),notify(,notifyAll()三个方法的调用者必须是同步代码块或者同步方法中的同步监视器,否则出现异常
(3)wait(),notify(,notifyAll()三个方法是定义在java.long.Object类中
package thread_communicate;public class thread_com {public static void main(String[] args) {number n=new number();Thread t1=new Thread(n);Thread t2=new Thread(n);t1.setName("线程1");t2.setName("线程2");t1.start();t2.start();}}class number implements Runnable{private int num=1;@Overridepublic void run() {while(true){synchronized(this){notify();if(num<=100){try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":"+num);num++;try {wait();} catch (InterruptedException e) {e.printStackTrace();}}else{break;}}}}}
sleep()和wait()方法的异同点:
1.相同点:一旦执行,都可使当前线程进入阻塞状态
2.不同点:(1)两个方法声明的位置不同:Thread类声明sleep,Object类声明wait
(2)调用范围不同:sleep可以在任何需要的场景下调用,wait必须在同步代码块或同步方法中(3)关于是否释放同步监视器:如果两个方法都在同步代码块或同步方法中,sleep不会释放同步监视器,而wait()会释放同步监视器
线程通信的应用:经典例题 :生产者/消费者问题
生产者将产品交给店员,消费者从店员取走产品,店员一次只能持有固定数量的产品;如果生产者试图生产更多的产品,店员会叫生产者停下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。package produce_cunsume;public class p_c {public static void main(String[] args) {clerk c=new clerk();producer pro=new producer(c);consumer con=new consumer(c);pro.setName("生产者");con.setName("消费者");pro.start();con.start();}}class clerk{private int product=0;public synchronized void pro_product(){if(product<20) {product++;System.out.println(Thread.currentThread().getName() + "开始生产第" + product + "个产品");notify();}else{try {wait();} catch (InterruptedException e) {e.printStackTrace();}}}public synchronized void con_product(){if(product>0){System.out.println(Thread.currentThread().getName()+"开始消费第"+product+"个产品");product--;notify();}else{try {wait();} catch (InterruptedException e) {e.printStackTrace();}}}}class producer extends Thread {private clerk c;public producer(clerk c) {this.c = c;}@Overridepublic void run() {System.out.println(getName()+"生产者开始生产...");while(true){try {sleep(10);} catch (InterruptedException e) {e.printStackTrace();}c.pro_product();}}}class consumer extends Thread{private clerk c;public consumer(clerk c){this.c=c;}@Overridepublic void run() {System.out.println(getName()+"消费者开始消费...");while(true){try {sleep(10);} catch (InterruptedException e) {e.printStackTrace();}c.con_product();}}}
