java 多线程,两个线程之间的通信

实例:两个线程轮流执行 

package com.heima.day25;

public class Demo004 {

	public static void main(String[] args) {
		
		Print print = new Print();
		
		
			new Thread(){
				public void run() {
					for(int i=1;i<=100;i++){
						try {
							print.print1();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				};
			}.start();
			
			new Thread(){
				public void run() {
					for(int i=1;i<=100;i++){
						try {
							print.print2();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				};
			}.start();


	}

}

class Print{
	
	private int flag = 1;
	
	/*
	 * 锁对象 为obj
	 * 如果调用wait()和notify()方法的不是锁对象,那么会报错
	 * java.lang.IllegalMonitorStateException
     * obj.wait() 和 obj.notify() 必须要在synchronized内调用否则报错
     *  java.lang.IllegalMonitorStateException
	 */
	Object obj = new Object();
	
	public void print1() throws InterruptedException{
		
		synchronized (obj) {
			
			if(flag!=1){
				obj.wait();
			}
			
			System.out.print("黑");
			System.out.print("马");
			System.out.print("程");
			System.out.print("序");
			System.out.print("员");
			System.out.print("\r\n");
			
			flag = 2;
			obj.notify();
			System.out.println(Thread.currentThread().getName());
		}
	}
	
	public void print2() throws InterruptedException{
		synchronized (obj) {
			
			if(flag != 2){
				obj.wait();
			}
			System.out.print("传");
			System.out.print("智");
			System.out.print("播");
			System.out.print("客");
			System.out.print("\r\n");
			
			flag = 1;
			obj.notify();
			System.out.println(Thread.currentThread().getName());
		}
	}
	
}

wait():导致当前线程等待并使其进入到等待阻塞状态。直到其他线程调用该同步锁对象的notify()或notifyAll()方法来唤醒此线程。

notify():唤醒在此同步锁对象上等待的单个线程,如果有多个线程都在此同步锁对象上等待,则会任意选择其中某个线程进行唤醒操作,只有当前线程放弃对同步锁对象的锁定,才可能执行被唤醒的线程。

注:wait() 和 notify()必须由锁对象来执行,否则会报错:java.lang.IllegalMonitorStateException。

 

一些资料:

《java编程思想》第四版一书中有描述到:“线程操作的wait()、notify()、notifyAll()方法只能在同步控制方法或同步控制块内调用。如果在非同步控制方法或控制块里调用,程序能通过编译,但运行的时候,将得到 IllegalMonitorStateException 异常,并伴随着一些含糊信息,比如 ‘当前线程不是拥有者’。其实异常的含义是 调用wait()、notify()、notifyAll()的任务在调用这些方法前必须 ‘拥有’(获取)对象的锁。”
 

你可能感兴趣的:(java)