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;
}