版本1
输出
版本2
输出
版本3
输出
版本4
输出
版本5
输出
版本6
输出
import java.util.LinkedList;
import java.util.List;
/**
* Producer Class in java, Producer will allow consumer to
* consume only when 10 products have been produced
* (i.e. when production is over).
*/
class Producer implements Runnable {
List < Integer > sharedQueue;
Producer() {
sharedQueue = new LinkedList < Integer > ();
}@Override
public void run() {
synchronized(this) {
for (int i = 1; i <= 10; i++) { //Producer will produce 10 products
sharedQueue.add(i);
System.out.println("Producer is still Producing, Produced : " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Production is over, consumer can consume.");
//Production is over, notify consumer thread so that consumer can consume.
this.notify();
}
}
}
/**
* Consumer Class.
*/
class Consumer extends Thread {
Producer prod;
Consumer(Producer obj) {
prod = obj;
}
public void run() {
/*
* consumer will wait till producer is producing.
*/
synchronized(this.prod) {
System.out.println("Consumer waiting for production to get over.");
try {
this.prod.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*production is over, consumer will start consuming.*/
int productSize = this.prod.sharedQueue.size();
for (int i = 0; i < productSize; i++)
System.out.println("CONSUMED : " + this.prod.sharedQueue.remove(0) + " ");
}
}
public class ProducerConsumerWithWaitNotify {
public static void main(String args[]) throws InterruptedException {
Producer prod = new Producer();
Consumer cons = new Consumer(prod);
Thread prodThread = new Thread(prod, "prodThread");
Thread consThread = new Thread(cons, "consThread");
consThread.start(); //start consumer thread.
Thread.sleep(100); //This minor delay will ensure that consumer thread starts before producer thread.
prodThread.start(); //start producer thread.
}
}
输出
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Producer is still Producing, Produced : 4
Producer is still Producing, Produced : 5
Producer is still Producing, Produced : 6
Producer is still Producing, Produced : 7
Producer is still Producing, Produced : 8
Producer is still Producing, Produced : 9
Producer is still Producing, Produced : 10
Production is over, consumer can consume.
CONSUMED : 1
CONSUMED : 2
CONSUMED : 3
CONSUMED : 4
CONSUMED : 5
CONSUMED : 6
CONSUMED : 7
CONSUMED : 8
CONSUMED : 9
CONSUMED : 10
版本2
import java.util.LinkedList;
import java.util.List;
/**
* Producer Class in java, Producer will allow consumer to consume only
* when 10 products have been produced (i.e. when production is over).
*/
class Producer implements Runnable {
boolean productionInProcess;
List < Integer > list;
Producer() {
//initially Producer will be producing, so make this productionInProcess true.
productionInProcess = true;
list = new LinkedList < Integer > ();
}@Override
public void run() {
for (int i = 1; i <= 10; i++) { //Producer will produce 10 products
list.add(i);
System.out.println("Producer is still Producing, Produced : " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/* Once production is over, make this productionInProcess false.
* Production is over, consumer can consume.
*/
productionInProcess = false;
}
}
/**
* Consumer Class.
*/
class Consumer extends Thread {
Producer prod;
Consumer(Producer obj) {
prod = obj;
}
public void run() {
/*
* consumer checks whether productionInProcess is true or not,
* if it's true, consumer will sleep and wake up after certain time
* and again check whether productionInProcess is true or false.
* process will repeat till productionInProcess is true.
* Once productionInProcess is false we'll exit below while loop.
*/
while (this.prod.productionInProcess) {
System.out.println("Consumer waiting for production to get over.");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*productionInProcess is false means production is over,
* consumer will start consuming. */
System.out.println("Production is over, consumer can consume.");
int productSize = this.prod.list.size();
for (int i = 0; i < productSize; i++)
System.out.println("CONSUMED : " + this.prod.list.remove(0) + " ");
}
}
public class ProducerConsumerWithoutWaitNotify {
public static void main(String args[]) {
Producer prod = new Producer();
Consumer cons = new Consumer(prod);
Thread prodThread = new Thread(prod, "prodThread");
Thread consThread = new Thread(cons, "consThread");
prodThread.start(); //start producer thread.
consThread.start(); //start consumer thread.
}
}
输出
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Producer is still Producing, Produced : 4
Consumer waiting for production to get over.
Producer is still Producing, Produced : 5
Producer is still Producing, Produced : 6
Producer is still Producing, Produced : 7
Producer is still Producing, Produced : 8
Consumer waiting for production to get over.
Producer is still Producing, Produced : 9
Producer is still Producing, Produced : 10
Production is over, consumer can consume.
CONSUMED : 1
CONSUMED : 2
CONSUMED : 3
CONSUMED : 4
CONSUMED : 5
CONSUMED : 6
CONSUMED : 7
CONSUMED : 8
CONSUMED : 9
CONSUMED : 10
版本3
import java.util.LinkedList;
import java.util.List;
/**
* Producer Class.
*/
class Producer implements Runnable {
private List < Integer > sharedQueue;
private int maxSize = 2; //maximum number of products which sharedQueue can hold at a time.
public Producer(List < Integer > sharedQueue) {
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) { //produce 10 products.
try {
produce(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void produce(int i) throws InterruptedException {
synchronized(sharedQueue) {
//if sharedQuey is full wait until consumer consumes.
while (sharedQueue.size() == maxSize) {
System.out.println("Queue is full, producerThread is waiting for " + "consumerThread to consume, sharedQueue's size= " + maxSize);
sharedQueue.wait();
}
}
/* 2 Synchronized blocks have been used means before
* producer produces by entering below synchronized
* block consumer can consume.
*/
//as soon as producer produces (by adding in sharedQueue) it notifies consumerThread.
synchronized(sharedQueue) {
System.out.println("Produced : " + i);
sharedQueue.add(i);
Thread.sleep((long)(Math.random() * 1000));
sharedQueue.notify();
}
}
}
/**
* Consumer Class.
*/
class Consumer implements Runnable {
private List < Integer > sharedQueue;
public Consumer(List < Integer > sharedQueue) {
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
while (true) {
try {
consume();
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void consume() throws InterruptedException {
synchronized(sharedQueue) {
//if sharedQuey is empty wait until producer produces.
while (sharedQueue.size() == 0) {
System.out.println("Queue is empty, consumerThread is waiting for " + "producerThread to produce, sharedQueue's size= 0");
sharedQueue.wait();
}
}
/* 2 Synchronized blocks have been used means before
* consumer start consuming by entering below synchronized
* block producer can produce.
*/
/*If sharedQueue not empty consumer will consume
* (by removing from sharedQueue) and notify the producerThread.
*/
synchronized(sharedQueue) {
Thread.sleep((long)(Math.random() * 2000));
System.out.println("CONSUMED : " + sharedQueue.remove(0));
sharedQueue.notify();
}
}
}
public class ProducerConsumerWaitNotify {
public static void main(String args[]) {
List < Integer > sharedQueue = new LinkedList < Integer > (); //Creating shared object
Producer producer = new Producer(sharedQueue);
Consumer consumer = new Consumer(sharedQueue);
Thread producerThread = new Thread(producer, "ProducerThread");
Thread consumerThread = new Thread(consumer, "ConsumerThread");
producerThread.start();
consumerThread.start();
}
}
输出
Queue is empty, consumerThread is waiting for producerThread to produce, sharedQueue's size= 0
Produced : 1
CONSUMED : 1
Produced : 2
CONSUMED : 2
Produced : 3
Produced : 4
CONSUMED : 3
Produced : 5
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 4
Produced : 6
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 5
Produced : 7
CONSUMED : 6
Produced : 8
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 7
Produced : 9
CONSUMED : 8
Produced : 10
CONSUMED : 9
CONSUMED : 10
Queue is empty, consumerThread is waiting for producerThread to produce, sharedQueue's size= 0
版本4
import java.util.LinkedList;
import java.util.List;
/**
* Implementing custom BlockingQueue interface .
* This BlockingQueue implementation follows FIFO (first-in-first-out).
* New elements are inserted at the tail of the queue,
* and removal elements is done at the head of the queue.
*/
interface BlockingQueueCustom < E > {
/**
* Inserts the specified element into this queue
* only if space is available else
* waits for space to become available.
*/
void put(E item) throws InterruptedException;
/**
* Retrieves and removes the head of this queue
* only if elements are available else
* waits for element to become available.
*/
E take() throws InterruptedException;
}
/**
* Implementing custom LinkedBlockingQueue class.
* This BlockingQueue implementation follows FIFO (first-in-first-out).
* New elements are inserted at the tail of the queue,
* and removal elements is done at the head of the queue.
*
*/
class LinkedBlockingQueueCustom < E > implements BlockingQueueCustom < E > {
private List < E > queue;
private int maxSize; //maximum number of elements queue can hold at a time.
public LinkedBlockingQueueCustom(int maxSize) {
this.maxSize = maxSize;
queue = new LinkedList < E > ();
}
/**
* Inserts the specified element into this queue
* only if space is available else
* waits for space to become available.
*/
public synchronized void put(E item) throws InterruptedException {
//check space is available or not.
if (queue.size() == maxSize) {
this.wait();
}
//space is available, insert.
queue.add(item);
this.notify();
}
/**
* Retrieves and removes the head of this queue
* only if elements are available else
* waits for element to become available.
*/
public synchronized E take() throws InterruptedException {
//waits element is available or not.
if (queue.size() == 0) {
this.wait();
}
//element is available, remove.
this.notify();
return queue.remove(0);
}
}
/**
* Producer Class in java
*/
class Producer implements Runnable {
private final BlockingQueueCustom < Integer > sharedQueue;
public Producer(BlockingQueueCustom < Integer > sharedQueue) {
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {
System.out.println("Produced : " + i);
//put/produce into sharedQueue.
sharedQueue.put(i);
} catch (InterruptedException ex) {
}
}
}
}
/**
* Consumer Class
*/
class Consumer implements Runnable {
private BlockingQueueCustom < Integer > sharedQueue;
public Consumer(BlockingQueueCustom < Integer > sharedQueue) {
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
while (true) {
try {
//take/consume from sharedQueue.
System.out.println("CONSUMED : " + sharedQueue.take());
} catch (InterruptedException ex) {
}
}
}
}
/**
* Main class
*/
public class ProducerConsumerBlockingQueueCustom {
public static void main(String args[]) {
BlockingQueueCustom < Integer > sharedQueue = new LinkedBlockingQueueCustom < Integer > (10); //Creating shared object
Producer producer = new Producer(sharedQueue);
Consumer consumer = new Consumer(sharedQueue);
Thread producerThread = new Thread(producer, "ProducerThread");
Thread consumerThread = new Thread(consumer, "ConsumerThread");
producerThread.start();
consumerThread.start();
}
}
输出
Produced : 1
Produced : 2
Produced : 3
CONSUMED : 1
Produced : 4
CONSUMED : 2
Produced : 5
CONSUMED : 3
Produced : 6
CONSUMED : 4
Produced : 7
CONSUMED : 5
Produced : 8
CONSUMED : 6
Produced : 9
CONSUMED : 7
Produced : 10
CONSUMED : 8
CONSUMED : 9
CONSUMED : 10
版本5
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Producer Class.
*/
class Producer implements Runnable {
private final BlockingQueue < Integer > sharedQueue;
public Producer(BlockingQueue < Integer > sharedQueue) {
this.sharedQueue = sharedQueue;
}@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {
System.out.println("Produced : " + i);
//put/produce into sharedQueue.
sharedQueue.put(i);
} catch (InterruptedException ex) {
}
}
}
}
/**
* Consumer Class.
*/
class Consumer implements Runnable {
private BlockingQueue < Integer > sharedQueue;
public Consumer(BlockingQueue < Integer > sharedQueue) {
this.sharedQueue = sharedQueue;
}@Override
public void run() {
while (true) {
try {
//take/consume from sharedQueue.
System.out.println("CONSUMED : " + sharedQueue.take());
} catch (InterruptedException ex) {}
}
}
}
public class ProducerConsumerBlockingQueue {
public static void main(String args[]) {
//Creating shared object
BlockingQueue < Integer > sharedQueue = new LinkedBlockingQueue < Integer > ();
Producer producer = new Producer(sharedQueue);
Consumer consumer = new Consumer(sharedQueue);
Thread producerThread = new Thread(producer, "ProducerThread");
Thread consumerThread = new Thread(consumer, "ConsumerThread");
producerThread.start();
consumerThread.start();
}
}
输出
Produced : 1
Produced : 2
CONSUMED : 1
Produced : 3
CONSUMED : 2
Produced : 4
CONSUMED : 3
Produced : 5
CONSUMED : 4
Produced : 6
CONSUMED : 5
Produced : 7
CONSUMED : 6
Produced : 8
CONSUMED : 7
Produced : 9
CONSUMED : 8
Produced : 10
CONSUMED : 9
CONSUMED : 10
版本6
import java.util.concurrent.Exchanger;
public class ExchangerTest {
public static void main(String[] args) {
Exchanger < String > exchanger = new Exchanger < String > ();
System.out.println("Exchanger has been created");
Producer prod = new Producer(exchanger);
Consumer cons = new Consumer(exchanger);
Thread prodThread = new Thread(prod, "prodThread");
Thread consThread = new Thread(cons, "consThread");
prodThread.start(); //start producer thread.
consThread.start(); //start consumer thread.
}
}
/**
* Producer Class.
*/
class Producer implements Runnable {
Exchanger < String > exchanger;
String str;
Producer(Exchanger < String > exchanger) {
str = new String();
this.exchanger = exchanger;
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
str += i;
System.out.println("Produced : " + i);
try {
str = exchanger.exchange(str);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* Consumer Class.
*/
class Consumer extends Thread {
Producer prod;
Exchanger < String > exchanger;
String str;
Consumer(Exchanger < String > exchanger) {
this.exchanger = exchanger;
}
public void run() {
for (int i = 0; i < 5; i++) {
try {
str = exchanger.exchange(new String());
System.out.println("CONSUMED : " + str);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出
Exchanger has been created
Produced : 1
CONSUMED : 1
Produced : 2
CONSUMED : 2
Produced : 3
CONSUMED : 3
Produced : 4
CONSUMED : 4
Produced : 5
CONSUMED : 5