生产者与消费者
wait()方法
- 方法wait()的作用是使当前执行代码的线程进行等待,wait()方法是Object类的方法,该方法是用来将当前线程置入“预执行队列”中,并且在wait()所在的代码处停止执行,直到接到通知或被中断为止。
- wait()方法只能在同步方法中或同步块中调用。如果调用wait()时,没有持有适当的锁,会抛出异常。
- wait()方法执行后,当前线程释放锁,线程与其它线程竞争重新获取锁。
notify()方法
-
方法notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁的其它线程,对其发出通知notify,并使它们重新获取该对象的对象锁。如果有多个线程等待,则有线程规划器随机挑选出一个呈wait状态的线程。
-
在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出同步代码块之后才会释放对象锁
class MyThread implements Runnable{
//
private Object object;
private boolean flag;
public MyThread(Object object,boolean flag){
this.object = object;
this.flag = flag;
}
public void waitMethod(){
synchronized (object){
System.out.println("wait方法开始。。"+Thread.currentThread().getName());
try{
object.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("wait方法结束。。"+Thread.currentThread().getName());
}
}
public void notifyMethod(){
synchronized (object){
System.out.println("notify方法开始。。"+Thread.currentThread().getName());
object.notifyAll();
System.out.println("notify方法结束。。"+Thread.currentThread().getName());
}
}
public void run(){
if(flag){
this.waitMethod();
}else{
this.notifyMethod();
}
}
}
class Test{
public static void main(String[] args) {
Object object = new Object();
MyThread mythread = new MyThread(object,true);
for(int i =0;i<10;i++){
Thread thread1 = new Thread(mythread,"wait线程"+i);
thread1.start();
}
MyThread mythread2 = new MyThread(object,false);
Thread thread3 = new Thread(mythread2);
thread3.start();
}
}
从结果上来看第一个线程执行的是一个waitMethod方法,该方法里面有个死循环并且使用了wait方法进入等待状态
将释放锁,如果这个线程不被唤醒的话将会一直等待下去,这个时候第二个线程执行的是notifyMethod方法,该方
法里面执行了一个唤醒线程的操作,并且一直将notify的同步代码块执行完毕之后才会释放锁然后继续执行wait结束
打印语句
notifyAll()方法
- 使用notifyAll()方法唤醒所有等待线程
class MyThread implements Runnable{
private Object object;
private boolean flag;
public MyThread(Object object,boolean flag){
this.object = object;
this.flag = flag;
}
public void waitMethod(){
synchronized (object){
System.out.println("wait方法开始。。"+Thread.currentThread().getName());
try{
object.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("wait方法结束。。"+Thread.currentThread().getName());
}
}
public void notifyMethod(){
synchronized (object){
System.out.println("notify方法开始。。"+Thread.currentThread().getName());
object.notifyAll();
System.out.println("notify方法结束。。"+Thread.currentThread().getName());
}
}
public void run(){
if(flag){
this.waitMethod();
}else{
this.notifyMethod();
}
}
}
class Test{
public static void main(String[] args) {
Object object = new Object();
MyThread mythread = new MyThread(object,true);
for(int i =0;i<10;i++){
Thread thread1 = new Thread(mythread,"wait线程"+i);
thread1.start();
}
MyThread mythread2 = new MyThread(object,false);
Thread thread3 = new Thread(mythread2);
thread3.start();
}
}
生产者与消费者模型
- 生产者与消费者开头已经介绍过了,生产者与消费者一般需要第三者来解耦的,所以现在就模拟一个简单的商品的生产者与消费者,由生产者线程生产出一个商品之后将由消费者线程开始消费
//商品类
class Goods{
private String goodName;
private int count;
//生产商品方法
public synchronized void set(String goodName){
//while
if(count > 0){
System.out.println("商品还有呐");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.goodName = goodName;
this.count++;
System.out.println(Thread.currentThread().getName()+"生产"+goodName+toString());
//唤醒等待消费的库存
notify();
//notifyAll();
}
//消费商品方法
public synchronized void get(){
//while
if(count == 0){
System.out.println("卖完啦~");
try {
//等待商品生产
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.count--;
System.out.println(Thread.currentThread().getName()+"消费"+goodName+toString());
//唤醒生产者生产
notify();
//notifyAll();
}
@Override
public String toString() {
return "Goods{" +
"goodName='" + goodName + '\'' +
", count=" + count +
'}';
}
}
//生产线程
class Producer implements Runnable{
private Goods goods;
public Producer(Goods goods){
this.goods = goods;
}
public void run(){
//while(true){
goods.set("牛排");
//}
}
}
//消费线程
class Consumer implements Runnable{
private Goods goods;
public Consumer(Goods goods){
this.goods = goods;
}
public void run(){
//while(true){
goods.get();
//}
}
}
class Test{
public static void main(String[] args) {
Goods good = new Goods();//同一个对象
Thread mythread = new Thread(new Producer(good),"生产者");
Thread mythread1 = new Thread(new Consumer(good),"消费者");
mythread.start();
mythread1.start();
// List<Thread> list = new ArrayList<>();
// for (int i = 0;i<10;i++){
// Thread thread new Thread(new Consumer(good),"xiaofeiz"+i);
// }
}
}