生产者消费者问题

11 篇文章 0 订阅
public class ProducerConsumer {
	
	public Product[] products = new Product[10];
	volatile int top = 0;
	volatile int capacity = 0;
	public static final Integer HOLD = 0;
	
	class Producer implements Runnable {
		public void produce(int i) throws InterruptedException {
			synchronized(HOLD) {
				while (capacity == products.length) {
					System.out.println("products are full...");
					HOLD.wait();
				}
				
				Product p = new Product(i);
				products[top++] = p;
				System.out.println("Producer :" + p);
				capacity++;
				Thread.sleep(500);
				HOLD.notifyAll();
			}
		}
		
		
		@Override
		public void run() {
			try {
				int i = 0;
				for (;;) {
					produce(i);
					i++;
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}

	class Consumer implements Runnable {
		
		public synchronized void consume() throws InterruptedException {
			while (!Thread.interrupted()) {
				synchronized(HOLD) {
					while (capacity == 0) {
						System.out.println("products is null....");
						HOLD.wait();
					}
					top--;
					Product p = products[top];
					System.out.println("Consumer : " + p);
					capacity--;
					Thread.sleep(500);
					HOLD.notifyAll();
				}
			}
		}
		
		@Override
		public void run() {
			try {
					consume();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}

	class Product {
		private int id;

		public Product(int id) {
			super();
			this.id = id;
		}

		@Override
		public String toString() {
			return "Product [id = " + id + "]";
		}
	}
	
	public static void main(String[] args) {
		ProducerConsumer test = new ProducerConsumer();
		new Thread(test.new Producer()).start();
		new Thread(test.new Consumer()).start();
	}
}

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

public class ProducerConsumer2 {
	public static void main(String[] args) {
		BlockingQueue<Integer> queue = new LinkedBlockingDeque<>();
		Producer p = new Producer(queue);
		Consumer<Integer> c1 = new Consumer<>(queue);
		Consumer<Integer> c2 = new Consumer<>(queue);
		new Thread(p).start();
		new Thread(c1).start();
		new Thread(c2).start();
	}
}

class Producer implements Runnable {
	private final BlockingQueue queue;
	private Integer i = 0;
	
	Producer(BlockingQueue q) {
		queue = q;
	}

	@Override
	public void run() {
		while (true) {
			try {
				queue.put(produce());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private int produce() {
		try {
			Thread.sleep(500);
			System.out.println(Thread.currentThread().getName() + " produce " + (++i));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return i;
	}
}

class Consumer<K> implements Runnable {
	private final BlockingQueue<K> queue;
	
	Consumer(BlockingQueue<K> q) {
		queue = q;
	}
	
	@Override
	public void run() {
		while (true) {
			try {
				consume(queue.take());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private void consume(K take) {
		System.out.println("---->" + Thread.currentThread().getName() + " consume " + take);
	}
	
}

1、所有对象都自动含有单一的锁(也称监视器)。当在对象上调用其任意synchronized方法时,此对象被加锁,这是该对象的其他synchronized方法只有等到前一个方法调用完毕并释放了锁之后才能被调用。

2、对于某个特定对象来说,其所有的synchronized方法共享同一个锁。

3、调用sleep()的时候并没有释放锁,调用yield()方法也是这样。在wait()期间锁是释放的。

4、只能在同步控制方法或同步控制块中调用wait()、notify()和notifyAll(),sleep()可以在非同步控制方法里调用。

5、当notifyAll()因某个特定锁而被调用时,只有等待 这个锁的任务才会唤醒。

6、使用while循环包围wait()。

7、基本上,如果一个域可能会被多个任务同时访问,或者这些任务中至少有一个是写入任务,那么你就应该将这个域设置为volatile的。

8、volatile关键字确保了应用中的可视性。volatile域会被立即写入到主存中。


C语言版的生产者消费者参考如下网址:http://blog.csdn.net/zgrjkflmkyc/article/details/8971894

#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>

/*******************************************************************
**实现生产者线程生产数据放入一个单向链表中,消费者线程负责消费数据**
*******************************************************************/

//单向链表数据结构
struct product {
	char		product_data[20];
	struct product	*pre_product;
	struct product	*next_product;
};

//向单向链表中加入一个节点(生产)。
void addProduct(char *product_data);
//从单向链表中取出全部节点信息(消费)。
void consProduct();
void consumer();
//生产者执行生产任务
void producer();

#define		MAX		 10
#define		MIN		 0

volatile int	total		 = 0;	//max capacity = 10
struct product	*present_product = NULL;
struct product	*pre_product	 = NULL;
int		lock		 = 0;

static	pthread_mutex_t		mutex;
static	pthread_cond_t		cond;

void addProduct(char *product_data) {
	pthread_mutex_lock(&mutex);
	while ( total == MAX ) {
		printf("Producer: I am waiting....\n");
		pthread_cond_wait(&cond, &mutex);
	}
	struct product *new_product = malloc(sizeof(struct product));
	if (present_product == NULL) {
		new_product -> pre_product = NULL;
		strcpy( new_product -> product_data, product_data);
		new_product -> next_product = NULL;
		present_product = new_product;
		total++;
		printf("produce data %s, total = %d\n", product_data, total);
	} else {
		new_product -> pre_product = present_product;
		strcpy( new_product -> product_data, product_data);
		new_product -> next_product = NULL;
		present_product -> next_product = new_product;
		present_product = new_product;
		total++;
		printf("produce data %s, total = %d\n", product_data, total);
	}
	sleep(1);
	pthread_mutex_unlock(&mutex);
	if (total == MIN + 1)
		pthread_cond_signal(&cond);
	//pthread_mutex_unlock(&mutex);
}

void consProduct() {
	pthread_mutex_lock(&mutex);
	while ( total == MIN ) {
		printf("Consumer: I am waiting....\n");
		pthread_cond_wait(&cond, &mutex);
	}
	if (present_product != NULL) {
		pre_product = present_product -> pre_product;
		printf("%s, total = %d\n", present_product -> product_data, total);

		if (pre_product != NULL) {
			pre_product -> next_product = 0;
		}

		free(present_product);
		present_product = pre_product;
		total--;
	}
	sleep(1);
	pthread_mutex_unlock(&mutex);
	if (total == MAX - 1)
		pthread_cond_signal(&cond);
	//pthread_mutex_unlock(&mutex);
}

void producer() {
	static int temp_i = 0;
	char temp[20] = { 0 };
	while( 1 ) {
		sprintf(temp, "number___%d", temp_i);
		addProduct(temp);
		temp_i++;
	}
}

void consumer() {
	while(1) {
		consProduct();
		printf("-------------\n");
		//usleep((int)(rand()/1000));
	}
}

int main() {
	int		res;
	pthread_t	thread_pro;
	pthread_t	thread_cons;

	printf("create....\n");   

	//创建生产者线程。
	res = pthread_create(&thread_pro, NULL, (void *)producer, NULL);
	if ( res != 0 ) {
		perror("Thread producer creation failed.\n");
		exit(-1);
	}

	//创建消费者线程。
	res = pthread_create(&thread_cons, NULL, (void *)consumer, NULL);
	if ( res != 0 ) {
		perror("Thread consumer creation failed.\n");
		exit(-1);
	}

	res = pthread_mutex_init(&mutex, NULL);
	if (res != 0) {
		perror("Mutex initialization failed.");
		exit(-1);
	}

	res = pthread_cond_init(&cond, NULL);
	if (res != 0) {
		perror("Condition initialization failed.");
		exit(-1);
	}

	printf("Waiting for thread to finish...\n");

	res = pthread_join(thread_pro, NULL);
	if ( res != 0 ) {
		perror("Thread producer join failed.\n");
		exit(-1);
	}
	res = pthread_join(thread_cons, NULL);
	if ( res != 0 ) {
		perror("Thread consumer join failed.\n");
		exit(-1);
	}

	printf("finished!\n");

	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值