线程--单消费和单生产

1 案例:生产与消费

       生产与消费同时执行(多线程),但是执行的任务不同,处理的资源一样。生产者每生产一个消费者就消费一个。

package com.java.example;
	
//	测试类
public class Thread01 {
		public static void main(String[] args) {
			//1.创建资源对象
			Resource r = new Resource();
			//2.创建线程任务,操作同一资源对象
			Producer p = new Producer(r);
			Consumer c = new Consumer(r);
			//3.创建线程
			Thread t1 = new Thread(p);//负责生产
			Thread t2 = new Thread(c);//负责消费
			//4.启动线程
			t1.start();
			t2.start();
		}
}
/*描述资源(面包)
 * 希望的结果是:生产一个面包就要消费一个面包
 * 什么情况下生产,什么情况下消费?
 * 当有面包时,则消费,当没有面包时,则生产
 * 定义标记来标记当前是否有面包
 * (1)如果标记为true,代表有面包,生产者先告诉消费者来消费,然后再进入到等待状态。
 * (2)如果标记为false,代表没有,消费者先告诉生产者来生产,然后再去等待*/
class Resource{
		//属性
		private String name;	//面包的名字
		private int count = 1;	//编号
		//	定义一个标记
		Boolean flag = false;
		//set()方法:对面包名字赋值
		public synchronized void set(String name){
			//flag为true,有面包,则进入等待状态
			if(flag){
				try {wait();} catch (InterruptedException e) {}
			}
			//	flag为false,没面包,生产者要进行生产。
			this.name = name+count;
			count++;
			System.out.println(Thread.currentThread().getName()
										+"---生产者---"+this.name);
			//	把标记改为true
			flag = true;
			//	唤醒消费者
			notify();
		}
		//get()方法:获取面包
		public synchronized void get(){
			//	如果flag为false,没有面包,则等进入等待状态
			if(!flag){
				try {wait();} catch (InterruptedException e) {}
			}
			//	flag为ture,有面包,消费者进行消费
			System.out.println(Thread.currentThread().getName()
								+"===消费者==="+this.name);
			//	把标记改为false
					flag = false;
					//	唤醒生产者
					notify();
		}
}
//描述生产者,具备自己的任务
class Producer implements Runnable{
		//要保证生产和消费处理的是一个资源对象,
		//就不能Resource r = new Resource();
		//解决方法:向方法中直接传参(参数:资源)
		private Resource r;
		public Producer(Resource r){
			this.r = r;	
		}
		@Override
		public void run() {
			//生产面包
			while(true){
				r.set("资溪面包");
			}
		}	
}
//描述消费者,具备自己的任务
class Consumer implements Runnable{
		private Resource r;
		public Consumer(Resource r){
			this.r = r;
		}
		@Override
		public void run() {
			//消费面包
			while(true){
				r.get();
			}
	}
}

分析:
       如果flag为true,有面包。生产者线程wait(),消费者消费,修改标识并唤醒生产者线程,生产者生产面包,消费者线程wait()。就这样保证了生产一个消费一个。

2 等待唤醒机制

       可以改变线程状态。
(1)wait():等待,让线程释放执行资格以及执行权,将线程临时存到线程池中,等待着被唤醒。
(2)notify():唤醒线程池中任意一个等待的线程
(3)notifyAll():会唤醒线程池中所有的等待线程
总结:这些方法必须使用在同步中,因为必须要标识wait,notify 等方法所属的锁,同一锁上的notify 只能够唤醒该锁上被wait的线程,
       为什么这些方法是操作线程的,但是却定义在了Object类中呢?
       因为这些方法必须要标识所属的锁是哪个对象,锁可以是任意对象类型,任意对象可以调用的方法就肯定是object类中的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值