Java生产者消费者实现

复习一下多线程

 

Customer.java

package com.example;

public class Customer implements Runnable{
	private Depository depository;

	public void setDepository(Depository depository) {
		this.depository = depository;
	}

	@Override
	public void run() {
		while(true) {
			depository.takeGood();
		}
		
	}
	
}

 

Productor.java

package com.example;

public class Producter implements Runnable{

	private Depository depository;
	
	@Override
	public void run() {
		while(true) {
			depository.addGood();
		}
	}
	
	public void setDepository(Depository depository) {
		this.depository = depository;
	}
}

 

Depository.java

package com.example;

public class Depository {
	private int count;
	public synchronized void takeGood() {
		if(count<=0) {
			try {
				System.out.println("It's empty!");
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}else {
			try {
				Thread.currentThread().sleep(25);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			count--;
			notifyAll();
			System.out.println(Thread.currentThread().getName()+" take a good");
			viewGoods();
		}
	}
	public synchronized void addGood() {
		if(count>=20) {
			try {
				System.out.println("It's full!");
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}else {
			try {
				Thread.currentThread().sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			count++;
			notifyAll();
			System.out.println(Thread.currentThread().getName()+" product a good");
			viewGoods();
		}
	}
	public void viewGoods() {
		System.out.println("now "+count+" goods");
	}
	public int getCount() {
		return count;
	}
}

 

Main.java

package com.example;

public class Main {

	public static void main(String[] args) {
		Depository depository = new Depository();
		
		Customer customer = new Customer();
		customer.setDepository(depository);
		
		Producter producter = new Producter();
		producter.setDepository(depository);
		
		Thread customer_1 = new Thread(customer);
		customer_1.setName("customer_1");
		customer_1.start();
		
		Thread customer_2 = new Thread(customer);
		customer_2.setName("customer_2");
		customer_2.start();
		
		Thread producter_ = new Thread(producter);
		producter_.setName("producter_");
		producter_.start();
	}

}

 

有几个点要说一下:

1.main没有中止,当然无伤大雅

2.如果线程实现都是用Runable接口,所有线程用的锁都是Runnable实现类的(与本例无关,本例使用Despository)

3.写打印输出的时候碰到的问题,还是要把所有日志写在同步代码块里,虽然对真实结果无影响,但会显示乱了。

4.把增加货物与减少货物写在了仓库类里,不是太好,之后会想一下写进各自的类

5.关于notifyAll,当需要调用的时候,阻塞的类一定是不同类(比如,当从0->1时,生产者(实际是Despository)notify的都是正在阻塞的消费者)

6.之前写的sleep是在生产者消费者循环里,输出比较好,比较符合实际放货物拿货物的情况,争夺锁的情况比较少;而本例中放在同步代码块中,是为了更明显的看到synchronized的作用。

7.更改生产者或消费者数量时,要注意调sleep时间,否则count很可能涨不起来。

以下输出,有一个问题是,每当同步方法执行完释放锁, 相比于上面6,为什么有那么多该线程仍旧抢到锁的情况?

输出:

It's empty!
It's empty!
producter_ product a good
now 1 goods
producter_ product a good
now 2 goods
producter_ product a good
now 3 goods
producter_ product a good
now 4 goods
producter_ product a good
now 5 goods
producter_ product a good
now 6 goods
producter_ product a good
now 7 goods
producter_ product a good
now 8 goods
producter_ product a good
now 9 goods
producter_ product a good
now 10 goods
producter_ product a good
now 11 goods
producter_ product a good
now 12 goods
producter_ product a good
now 13 goods
producter_ product a good
now 14 goods
producter_ product a good
now 15 goods
producter_ product a good
now 16 goods
producter_ product a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods
It's full!
customer_1 take a good
now 19 goods
customer_2 take a good
now 18 goods
customer_2 take a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods
It's full!
customer_1 take a good
now 19 goods
customer_1 take a good
now 18 goods
customer_1 take a good
now 17 goods
customer_1 take a good
now 16 goods
producter_ product a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods
It's full!
customer_2 take a good
now 19 goods
customer_2 take a good
now 18 goods
customer_2 take a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods
It's full!
customer_1 take a good
now 19 goods
customer_1 take a good
now 18 goods
customer_1 take a good
now 17 goods
customer_1 take a good
now 16 goods
customer_1 take a good
now 15 goods
customer_1 take a good
now 14 goods
customer_1 take a good
now 13 goods
customer_1 take a good
now 12 goods
customer_1 take a good
now 11 goods
customer_1 take a good
now 10 goods
producter_ product a good
now 11 goods
producter_ product a good
now 12 goods
producter_ product a good
now 13 goods
producter_ product a good
now 14 goods
producter_ product a good
now 15 goods
producter_ product a good
now 16 goods
producter_ product a good
now 17 goods
producter_ product a good
now 18 goods
producter_ product a good
now 19 goods
producter_ product a good
now 20 goods

It's full!


更新:synchronized并不能保证所有线程平等抢同步代码块的执行权

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值