简单的多生产多消费模式代码

资源描述类:

/**
 * 资源描述类
 * @author gaojh
 *
 */
public class Product {
	
	List<String> product = null;

	public Product() {
		super();
		this.product = new ArrayList<>();
	} 

	/**
	 * 生产方法
	 * @author: gaojh
	 * @throws InterruptedException 
	 * @date: 2018年4月16日 下午3:53:29
	 */
	public synchronized void produce() throws InterruptedException{
		if(product != null && product.size() < 1000){ //仅在产品List不为null且长度小于10时进行生产
			String singleProduct =  Thread.currentThread().getName() + "的产品";
			product.add(singleProduct);
			System.out.println(Thread.currentThread().getName()+"生产了"+singleProduct);
		}else{
			System.out.println(Thread.currentThread().getName()+"开始唤醒了");
			this.notifyAll();
			System.out.println(Thread.currentThread().getName()+"进入wait了");
			this.wait();
		}
	}
	
	
	/**
	 * 消费方法
	 * @author: gaojh
	 * @throws InterruptedException 
	 * @date: 2018年4月16日 下午3:53:29
	 */
	public synchronized void consume() throws InterruptedException{
		
		if(product != null && product.size() > 0){ //仅在产品List不为null且长度大于0时进行消费
			String singleProduct =  product.remove(0); //消费第一个
			System.out.println(Thread.currentThread().getName()+"消费了"+singleProduct);
		}else{
			System.out.println(Thread.currentThread().getName()+"开始唤醒了");
			this.notifyAll();
			System.out.println(Thread.currentThread().getName()+"进入wait了");
			this.wait();
		}
		
	}
	
}

生产者:

/**
 * 生产者类
 * @author gaojh
 *
 */
public class Producer implements Runnable{
	
	Product product = null;
	
	public Producer(Product product) {
		super();
		this.product = product;
	}
	
	@Override
	public void run() {
		//生产逻辑
		try {
			while(true){
				product.produce();
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

消费者:

/**
 * 消费者类
 * @author gaojh
 *
 */
public class Consumer implements Runnable{
	
	Product product = null;
	
	public Consumer(Product product) {
		super();
		this.product = product;
	}

	@Override
	public void run() {
		//消费逻辑
		try {
			while(true){
				product.consume();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Main方法类:

/**
 * 测试多生产多消费
 * @author gaojh
 *
 */
public class TestThread {
	
	public static void main(String[] args) {
		Product product = new Product(); //创建唯一资源
		
		//生产者
		Producer producer = new Producer(product);
		
		Thread producer1 = new Thread(producer); //生产者1
		producer1.setName("生产者1");
		Thread producer2 = new Thread(producer); //生产者2
		producer2.setName("生产者2");
		Thread producer3 = new Thread(producer); //生产者3
		producer3.setName("生产者3");
		
		producer1.start();
		producer2.start();
		producer3.start();
		
		//消费者
		Consumer consumer = new Consumer(product);
		
		Thread consumer1 = new Thread(consumer); //消费者1
		consumer1.setName("消费者1");
		Thread consumer2 = new Thread(consumer); //消费者2
		consumer2.setName("消费者2");
		Thread consumer3 = new Thread(consumer); //消费者3
		consumer3.setName("消费者3");
		consumer1.start();
		consumer2.start();
		consumer3.start();
		
	}
}


问:为什么在notifyAll之后让当前线程wait?

答:当前线程既然已经执行到notifyAll了,说明当前线程该做的及该类型线程该做的都已经完成了,如果下次竞争syn的锁,当前线程再次竞争持有(很有可能),只是进来唤醒了其他线程而已,没有必要,wait至少可以让当前线程释放锁,等待被唤醒。这样竞争线程从6个变为5个,无论是生产者还是消费者进入等待,对方线程只有syn锁的数字几率都会变大。


PS:现在在产品满了/空了后,无法指定唤醒消费者/生产者,只能全部唤起然后一个一个判断。效率上不行,要想办法修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的RocketMQ顺序生产者的示例代码: ```java import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.common.message.Message; import org.apache.rocketmq.common.message.MessageQueue; import org.apache.rocketmq.remoting.common.RemotingHelper; import java.util.List; public class OrderProducer { public static void main(String[] args) throws Exception { // 创建生产者实例 DefaultMQProducer producer = new DefaultMQProducer("ExampleProducerGroup"); // 指定NameServer地址 producer.setNamesrvAddr("localhost:9876"); // 启动生产者 producer.start(); // 模拟生成一些订单消息 List<OrderMessage> orderMessages = OrderMessage.createOrderMessages(); // 对每个订单消息进行发送 for (OrderMessage orderMessage : orderMessages) { Message message = new Message("OrderTopic", "order", orderMessage.getId().getBytes(RemotingHelper.DEFAULT_CHARSET)); // 设置消息的顺序关键词 message.setKeys(String.valueOf(orderMessage.getId())); // 发送消息并获取消息队列 MessageQueue messageQueue = producer.send(message, new AllocateMessageQueueStrategy() { @Override public List<MessageQueue> allocate(String s, String s1, List<MessageQueue> messageQueues, String s2) { return messageQueues; } }, orderMessage.getId()); System.out.printf("Send order message: %s, queue: %s%n", orderMessage, messageQueue); } // 关闭生产者 producer.shutdown(); } } class OrderMessage { private long id; private String content; public OrderMessage(long id, String content) { this.id = id; this.content = content; } public long getId() { return id; } public String getContent() { return content; } public static List<OrderMessage> createOrderMessages() { return List.of( new OrderMessage(1, "First order"), new OrderMessage(2, "Second order"), new OrderMessage(3, "Third order"), new OrderMessage(1, "Fourth order"), new OrderMessage(2, "Fifth order"), new OrderMessage(3, "Sixth order") ); } @Override public String toString() { return "OrderMessage{" + "id=" + id + ", content='" + content + '\'' + '}'; } } ``` 该示例代码创建了一个`DefaultMQProducer`对象,连接到了指定的NameServer地址,构造了几条订单消息`OrderMessage`,并将其发送到`OrderTopic`主题。在发送消息时,注意给每个消息设置了顺序关键词,保证了消息是有序的。 在这里,为了实现顺序发送消息,我们使用了一个自定义的`AllocateMessageQueueStrategy`实现类,它通过直接返回消息队列列表来确保消息按照订单编号进行顺序发送到同一个消息队列中。 需要注意的是,RocketMQ并不能保证每个消息都按照顺序消费,但是它能够保证每个消息队列中的消息按照顺序被消费。因此,在使用顺序消息的同时,也需要对消息的发送进行合理的控制和处理,以确保消息能够按照期望的顺序被消费
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值