2016-08-19-java-关于线程的死锁的案例分析:生产者消费者问题

本文通过两个版本的Java代码示例介绍了生产者消费者模型的实现方法。第一版使用简单的条件判断和等待通知机制来控制生产者和消费者的同步;第二版则进一步优化,增加了面包数量的限制,使得生产和消费更加贴近实际场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

同步问题Java解决方案:

同步方法:当线程进入同步方法的时候,会获得同步方法所属的锁,一旦获得对象锁,则其他线程不能再执行被锁对象的其他任何同步方法。

只有在同步方法执行完毕之后释放锁,其他线程才能执行。

同步块:....



版本一(本人自己版):

package com.shi.onclass;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 关于生产者消费者线程的问题
 * 两个对象:做面包的||吃面包的
 * 两个方法:吃面包的方法||做面包的方法
 * @author Shi
 * 1.定一个数组对象存放我的面包
 * 2.定一个面包个数的最大值
 * 
 */
public class Shop {
	List<String> data = new ArrayList<String>();
	public void produce(){
		synchronized (data) {
			if(data.size()>0){
				System.out.println("可以卖面包了");
				data.notify();
				try {
					data.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			String a = "面包"+System.currentTimeMillis();
			data.add(a);
			System.out.println("生成了:"+a+",找人来吃,现在面包个数为:"+data.size());
			//data.notify();
		}
		
	}
	
	public void sale(){
		synchronized (data) {
			if(data.size()==0){
				try {
					System.out.println("没面包了该通知做面包了");
					data.notify();
					data.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			String s = data.get(0);
			data.remove(0);
			System.out.println("吃掉了面包"+s);
			data.notify();
		}
		
	}
	
	public static void main(String[] args) {
		Shop shop = new Shop();
		Thread productor = new Thread(new Productor(shop));
		Thread customer = new Thread(new Customer(shop));
		productor.start();
		customer.start();
		
		
	}
}
class Productor implements Runnable{
	Shop shop;
	
	public Productor(Shop shop) {
		super();
		this.shop = shop;
	}

	@Override
	public void run() {
		while(true){
			shop.produce();
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
		// TODO Auto-generated method stub
		
	}
}
class Customer implements Runnable{
	Shop shop;

	public Customer(Shop shop) {
		super();
		this.shop = shop;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			shop.sale();
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
		
	}
}

版本二(改进老师版本,还是自己写的版本。。。。)

package com.shi.onclass;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 关于生产者消费者线程的问题
 * 两个对象:做面包的||吃面包的
 * 两个方法:吃面包的方法||做面包的方法
 * @author Shi
 * 1.定一个数组对象存放我的面包
 * 2.定一个面包个数的最大值
 * 
 */
public class Shop {
	List<String> data = new ArrayList<String>();
	static final int MAX = 10;
	
	public Shop() {
		for(int i =0 ;i<5;i++){
			data.add("面包"+System.currentTimeMillis());
		}
	}
	public void product(){
		synchronized (data) {
			if(data.size()==MAX){
			System.out.println("面包已满!等人吃了在做");
			data.notify();//通知吃面包的人来吃面包
			try {
				data.wait();//等吃人吃了,收到做面包的通知再做面包
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return;
		}
		String s = "面包"+System.currentTimeMillis();
		data.add(s);
		System.out.println("生成了:"+s+",找人来吃,现在面包个数为:"+data.size());
		data.notify();
		}
		
	}
	public void eat(){
		synchronized (data) {
			if(data.size()==0){
			System.out.println("面包没了,通知人来做");
			data.notify();//通知发出
			try {
				data.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return;
		}
		String s = data.get(0);
		data.remove(s);
		System.out.println("消费了"+s+",并通知生成,还剩面包个数为:"+data.size());
		data.notify();
		}
		
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Shop shop= new Shop();
		Thread productor = new Thread(new Productor(shop));
		Thread custmor = new Thread(new Customer(shop));
		productor.start();
		custmor.start();
	}
}

//生产者线程
class Productor implements Runnable{
	Shop shop;
	Random r = new Random();
	public Productor(Shop shop) {
		super();
		this.shop = shop;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			shop.product();
			try {
				Thread.sleep(100+r.nextInt(200));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
class Customer implements Runnable{
	Shop shop;
	Random r = new Random();
	public Customer(Shop shop) {
		super();
		this.shop = shop;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			shop.eat();
			try {
				Thread.sleep(100+r.nextInt(200));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值