并发编程11-wait,notify

30 篇文章 0 订阅

1.wait,notify概述

  • 目的是实现线程通信
  • wait和notify都需要放在synchronized(方法和代码块都行)中.
  • 在碰到wait之后,synchronized就被释放了.
  • notify叫醒一个线程,notifyAll会叫醒多个线程(一个个的进行),
  • 可以通过Jconsole来查看wait的线程

2.示例

2.1 在不用wait,notify的情况下实现线程通信


/**
 * 在不用wiat/notify的情况下,实现线程通信
 * while 和 sleep,消耗性能或者不能及时通信.
 */
public class SignalCommunication {

	private volatile int signal;

	public void set (int value) {
		this.signal = value;
	}

	public int get () {
		return signal;
	}

	public static void main(String[] args) {
		SignalCommunication d = new SignalCommunication();
		new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("修改状态的线程执行...");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				d.set(1);
				System.out.println("状态值修改成功。。。");
			}
		}).start();


		new Thread(new Runnable() {

			@Override
			public void run() {

				// 等待signal为1开始执行,否则不能执行
				while(d.get() != 1) {
					try {
						Thread.sleep(1500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				// 当信号为1 的时候,执行代码
				System.out.println("模拟代码的执行...");


			}
		}).start();
	}
}

2.2 通过wait,notify实现线程通信

  • 匿名类new thread然后多线程的线程通信(过wait,notifyl)

/**
 wait和notify都需要放在synchronized中.
 在碰到wait之后,synchronized就被释放了.否则线程就一直等待了.
 notify或notifyall之后会加锁

 一.这里采用的是匿名类new thread然后多线程的线程通信.
 */
public class WaitNotifyCommunication {

	private volatile int signal;

	public void set (int value) {
		this.signal = value;
	}

	public int get () {
		return signal;
	}

	public static void main(String[] args) {
		WaitNotifyCommunication waitNotifyCommunication = new WaitNotifyCommunication();

		//1.需要有synchronized锁需要通信的对象
		//2.wait和notify都要是一个对象.


		new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (waitNotifyCommunication) {
					System.out.println("修改状态的线程执行...");
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					waitNotifyCommunication.set(1);
					System.out.println("状态值修改成功。。。");
					waitNotifyCommunication.notify();
					//notify();如果这里直接notify,唤醒的是当前线程,也就是new Thread()这个线程.
				}
			}
		}).start();


		new Thread(new Runnable() {

			@Override
			public void run() {
				synchronized (waitNotifyCommunication) {
					// 等待signal为1开始执行,否则不能执行
					while(waitNotifyCommunication.get() != 1) {
						try {
							waitNotifyCommunication.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					// 当信号为1 的时候,执行代码
					System.out.println("模拟代码的执行...");
				}
			}
		}).start();
	}

}

2.3 通过wait,notifyall实现线程通信

  • 实现多线程的线程通信(过wait,notifyall)
  • Thread1 线程1,Thread2 线程2,WaitNotifyAllCommunication 线程通信,执行函数main

public class Thread1 implements Runnable {

    private WaitNotifyAllCommunication waitNotifyAllCommunication;

    public Thread1(WaitNotifyAllCommunication waitNotifyAllCommunication) {
        this.waitNotifyAllCommunication = waitNotifyAllCommunication;
    }

    @Override
    public void run() {
        waitNotifyAllCommunication.set();
    }
}


public class Thread2 implements Runnable {

	private WaitNotifyAllCommunication waitNotifyAllCommunication;

	public Thread2(WaitNotifyAllCommunication waitNotifyAllCommunication) {
		this.waitNotifyAllCommunication = waitNotifyAllCommunication;
	}

	@Override
	public void run() {
		waitNotifyAllCommunication.get();
	}

}


/**
  waitall和notifyall都需要放在synchronized中.
 在碰到wait之后,synchronized就被释放了.否则线程就一直等待了.
 notify或notifyall之后会加锁

 * 二.这里采用的是实现的类然后多线程的例子线程通信
 */
public class WaitNotifyAllCommunication {

	private volatile int signal;

	public synchronized void set () {
		signal = 1;
		// notify方法会随机叫醒一个处于wait状态的线程
		notifyAll(); // notifyAll叫醒所有的处于wait线程,争夺到时间片的线程只有一个
		System.out.println("叫醒线程叫醒之后休眠开始...");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public synchronized int get () {
		System.out.println(Thread.currentThread().getName() + " 方法执行了...");
		if(signal != 1) {
			try {
				wait();
				System.out.println("叫醒之后");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println(Thread.currentThread().getName() + " 方法执行完毕...");
		return signal;
	}


	/**
	 //这个的执行过程很值得体会下.
	 *
	 Thread-1 方法执行了...
	 Thread-2 方法执行了...
	 Thread-0 方法执行了...
	 Thread-3 方法执行了...
	 叫醒线程叫醒之后休眠开始...
	 叫醒之后
	 Thread-3 方法执行完毕...
	 叫醒之后
	 Thread-0 方法执行完毕...
	 叫醒之后
	 Thread-2 方法执行完毕...
	 叫醒之后
	 Thread-1 方法执行完毕...

	 Process finished with exit code 0

	 */
	public static void main(String[] args) {

		WaitNotifyAllCommunication d = new WaitNotifyAllCommunication();
		Thread1 t1 = new Thread1(d);	//thread1是 set
		Thread2 t2 = new Thread2(d);	//thread2是 get

		new Thread(t2).start();
		new Thread(t2).start();
		new Thread(t2).start();
		new Thread(t2).start();

		//这个也可以是线程的休眠.
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		new Thread(t1).start();

	}
}

2.4 wait,notify模式生产者消费者

  • Warehouse1 工厂(生产/消费机器)
  • PushTarget 生产者
  • TakeTarget 消费者
  • Main 执行函数

public class Warehouse1 {

   private int count;

   public final int MAX_COUNT = 10;

   public synchronized void push () {
   	while(count >= MAX_COUNT) {
   		try {
   			System.out.println(Thread.currentThread().getName() + " 库存数量达到上限,生产者停止生产。");
   			wait();
   		} catch (InterruptedException e) {
   			e.printStackTrace();
   		}
   	}
   	count ++;
   	System.out.println(Thread.currentThread().getName() + " 生产者生产,当前库存为:" + count);
   	notifyAll();
   }

   public synchronized void take () {

   	while(count <= 0) {
   		try {
   			System.out.println(Thread.currentThread().getName() + " 库存数量为零,消费者等待。");
   			wait();
   		} catch (InterruptedException e) {
   			e.printStackTrace();
   		}
   	}
   	count --;
   	System.out.println(Thread.currentThread().getName() + " 消费者消费,当前库存为:" + count);
   	notifyAll();
   }

}


public class PushTarget implements Runnable {

   private Producer1 producer1;

   public PushTarget(Producer1 producer1) {
   	this.producer1 = producer1;
   }

   @Override
   public void run() {
   	while(true) {
   		producer1.push();
   		try {
   			Thread.sleep(1000);
   		} catch (InterruptedException e) {
   			e.printStackTrace();
   		}
   	}
   }

}


public class TakeTarget implements Runnable {

   private Producer1 producer1;

   public TakeTarget(Producer1 producer1) {
   	this.producer1 = producer1;
   }

   @Override
   public void run() {
   	while(true) {
   		producer1.take();
   		try {
   			Thread.sleep(1000);
   		} catch (InterruptedException e) {
   			e.printStackTrace();
   		}
   	}
   }

}


public class Main {

   public static void main(String[] args) {

   	Producer1 producer1 = new Producer1();

   	PushTarget p = new PushTarget(producer1);
   	TakeTarget t = new TakeTarget(producer1);

   	new Thread(p).start();
   	new Thread(p).start();
   	new Thread(p).start();
   	new Thread(p).start();
   	new Thread(p).start();

   	new Thread(t).start();
   	new Thread(t).start();
   	new Thread(t).start();
   	new Thread(t).start();
   	new Thread(t).start();
   	new Thread(t).start();
   	new Thread(t).start();
   	new Thread(t).start();
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值