线程通讯,详细解析

1 篇文章 0 订阅
1 篇文章 0 订阅

线程通讯,详细解析

/*
	这里先做一个解释,为什么要线程通讯:在多个线程操作共享资源的时候,会出现混乱状态。
	例如:
		【汽车制造商】 与 【消费者】 的一个关系,这里的共享资源我们可以理解为车子。
		假如汽车制造商还没有生产出汽车,消费者怎么去购买汽车呢?
		1.在多线程中汽车制造商是一个线程,消费者是一个线程,两个线程去操控一个车子;
		就会有很大的可能出现生产商还没有造出车子,消费者就买了。这里使用线程同步也是控制不了这种情况的。
		线程同步:只是让线程一个一个的去访问这个共享资源。
		很明显这是解决不了这种问题的:
		CPU在执行这两个线程,这两个优先级都是5,分配是随机的。
		生产线程访问汽车,造出一台车,然后CPU执行了消费者线程,就消费者一辆车,CPU释放,操作系统再次分CPU的时候不一定分给哪一个线程,若分给了消费者线程,就又消费了一台车,这很明显不符合常理,造了一台车,被消费了两次。
		为了解决这个问题,就有了线程通讯,让线程之间相互交流,来把控线程的走势。这里需要借助两个Object类的三个方法:
		void wait();当前线程放弃线程锁,进入阻塞状态,只有调用了notify(),notifyAll()才会进入可运行状态。这里调用的时候尽量用共享资源的类对象调用,锁对象。
		void notify(); 唤醒同步锁上的等待的第一个wait()线程
		void notifyAll();唤醒这个同步锁上的调用wait()方法的所有线程
	利用这些方法实现生活中真正的逻辑。
	好啦!!大家看演示吧!看一下就懂了,就知道这是做什么的了!!
*/
//这是一个共享商品类
class Car{
	private String name;
    //车子的价格
	private int pic;
    //这个变量用于线程之间媒介
	private boolean falg;
	
	public Car() {
		super();
	}

	public Car(String name, int pic, boolean falg) {
		super();
		this.name = name;
		this.pic = pic;
		this.falg = falg;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPic() {
		return pic;
	}

	public void setPic(int pic) {
		this.pic = pic;
	}

	public boolean isFalg() {
		return falg;
	}

	public void setFalg(boolean falg) {
		this.falg = falg;
	}

	@Override
	public String toString() {
		return "Car [name=" + name + ", pic=" + pic + ", falg=" + falg + "]";
	}
	
}

class Producer implements Runnable{
	private Car c;
	private int a;
	
	public Producer(Car c) {
		super();
		this.c = c;
	}

	@Override
	public void run() {
		
		while(a < 50) {
			//这里之所以加锁是因为,防止多个线程对共享资源修改或访问,都是在访问Car类
			synchronized (c) {
				//这里做一个判断,看是否要生产汽车
				if(c.isFalg()) {
					
					System.out.println("生产了一辆 " + c.getName() + "售价:" + c.getPic());
					//这里把falg设置false是用于两个线程的通讯,这里一旦false,就停止造车了;这个是一个很重要的媒介
					c.setFalg(false);
					//这个变量是用于跳出循环
					a++;
					//这里是让等待的线程进入可运行状态,也就是唤醒消费者线程
					c.notify();
				} else {
					try {
						//让此线程进入休眠状态
						c.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}	
		}
	}
	
}
class Consumer implements Runnable{
	private Car c;
	
	public Consumer(Car c) {
		super();
		this.c = c;
	}

	@Override
	public void run() {
		
		while(true) {
			synchronized (c) {
				//这里就用到了falg,取它的非,开始消费这台车
				if(!c.isFalg()) {
					System.out.println("购买了 " + c.getName() + "售价:" + c.getPic());
					//已经消费完了,通知生产者,可以造车了
					c.setFalg(true);
					//这里是在唤醒生产者的线程
					c.notify();
					
				} else {
					try {
						//为了避免出现车还没有造出来,就消费了,所以消费线程需要等待一下
						c.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
		
	}
	
}

public class Demo {

	public static void main(String[] args) {
		//初始化汽车类对象,这里把falg的值设置为true,为了先让造车
		Car c = new Car("奔驰c200L",300000,true);
		Thread t1 = new Thread(new Producer(c));
		Thread t2 = new Thread(new Consumer(c));
		t1.start();
		//这里设置为后台线程,是因为当所有线程都运行完毕,这个消费者线程会自动消失,就如生活中一样,没有造车的,何谈买车?
		t2.setDaemon(true);
		t2.start();
	}

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值