Thread线程间通讯-wait,notify

解释:

When two or more threads need access to a shared resource, they need some way to ensure that the resource will be used by only one thread at a time.

The process by which this synchronization is achieved is called threadsynchronization.

The synchronized keyword in Java creates a block of code referred to as a critical section. Every Java object with a critical section of code gets a lock associated with the object. To enter a critical section, a thread needs to obtain the corresponding object'slock.

This is the general form of the synchronized statement:

synchronized(object) {
   // statements to be synchronized
}

Here, object is a reference to the object being synchronized. A synchronized block ensures that a call to a method that is a member of object occurs only after the current thread has successfully entered object's monitor.

/**

 * 线程间通讯:

 * 其实就是多个线程在操作同一个资源

 * 但是操作的动作不同

 */

wait, notify, notifyAll()

 都是用在同步中,因为要对持有监视器(锁)的线程操作。

 所以要使用在同步中,因为只有同步才具有锁。

 

 为什么这些操作线程的方法,要定义在object类中呢?

 因为这些方法在操作同步中线程时,都必须要标识他们所操作线程持有的锁,

 只有同一个锁上得被等待线程,可以被统一个锁上得notify唤醒。

 不可以对不同锁中的线程进行唤醒。

 也就是说,等待和唤醒必须是同一个锁。

 

 而锁可以是任意对象,所以可以被任意对象调用的方法(wait, notify,notifyAll)定义在object类中



举例:Input类用于,传入内容,Output类用于传出内容,由于传输的数据是共享的,所以将这个传输的数据对象作为“锁”。

等待====》唤醒

为了能够输入线程,和输出线程一次只运行一个线程,于是:输入线程工作,输出等待,输入线程等待,输出线程工作。


由于此例中进加入了两个线程,所以使用notify来唤醒wait状态下的线程。

notify 只唤醒在线程池中最上面的那个线程

notify 唤醒线程池中所有的线程


public class Input implements Runnable {

	private Res r;

	public Input(Res r) {
		super();
		this.r = r;
	}

	@Override
	public void run() {
		int x = 0;
		while (true) {
			synchronized (r) {
				if (r.flag)
					try {
						r.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				if (x == 0) {
					r.name = "LI";
					r.sex = "femal";
				} else {
					r.name = "李雷";
					r.sex = "男";
				}
				x = (x + 1) % 2;
				r.flag = true;
				r.notify();
			}
		}
	}

}

public class Output implements Runnable {

	private Res r;

	public Output(Res r) {
		super();
		this.r = r;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (r) {
				if (!r.flag)
					try {
						r.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				System.out.println(r.name + "," + r.sex);
				r.flag = false;
				r.notify();
			}
		}
	}

}

public class Res {

	String name;
	String sex;
	boolean flag = false;

}

public class InputOutputDemo {
	public static void main(String[] args) {
		Res r = new Res();
		
		Input in = new Input(r);
		Output out = new Output(r);
		
		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);
		
		t1.start();
		t2.start();
	}
}


由于共享对象是Res,可以将同步内容都放在Res中:
public class Res {

	private String name;
	private String sex;
	private boolean flag = false;

	public synchronized void set(String name, String sex) {

		if (flag)
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		this.name = name;
		this.sex = sex;

		flag = true;
		this.notify();
	}

	public synchronized void out() {

		if (!flag)
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		System.out.println(name + "..." + sex);

		flag = false;
		this.notify();
	}

}

public class Input implements Runnable {

	private Res r;

	public Input(Res r) {
		super();
		this.r = r;
	}

	@Override
	public void run() {
		int x = 0;
		while (true) {

			if (x == 0)
				r.set("Li", "female");
			else
				r.set("李雷", "男");

			x = (x + 1) % 2;
		}
	}
}

public class Output implements Runnable {

	private Res r;

	public Output(Res r) {
		super();
		this.r = r;
	}

	@Override
	public void run() {
		while (true) {
			r.out();
		}
	}

}


public class InputOutputDemo {
	public static void main(String[] args) {
		Res r = new Res();

		new Thread(new Input(r)).start();
		new Thread(new Output(r)).start();

	}
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值