Java Threads producer-consumer shared buffer [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Implement producer consumer problem using threads in Java. Producers and consumers share a buffer, producers put elements in buffer and consumers consume elements from the shared buffer. If the buffer is full producers should wait till consumers take out elements, similarly consumers should wait till producers put elements if the buffer is empty.
Your program should accept the following inputs:
m: the number of producer threads
n: the number of consumer threads
k: the size of the bounded buffer
Your code should prompt for the above inputs in that order. You can assume that a valid integer is provided by the user for each of these. You will need to spawn m Producer threads and n Consumer threads. Each producer generates 20 integers ranging between 0 and 9 and puts them in the buffer. After putting a number in the buffer, it prints its id along with the generated number. The producer sleeps for a random amount of time before repeating the number generating cycle again. Each consumer takes a number from the buffer then prints its id along with the value it got. Then, it sleeps for a random amount of time before reading from the buffer again.
A sample output of the program is:
Producer #2 put: 1
Producer #1 put: 4
Consumer #3 got: 1
Producer #1 put: 3
Consumer #3 got: 4
Consumer #3 got: 3
...
i have this problem. it is clear that the array of buffer is a global variable for two method because of that array is shared with Producer & Consumer. so? Unfortunately i have no idea how to do this project. anybody have an idea?

import java.security.SecureRandom;
import java.util.concurrent.*;
/**
* Created by Leon.H on 2016/1/13.
*/
public class ProducerConsumer {
private int producerNumber = 0;
private int consumerNumber = 0;
private int bufferSize = 0;
private final int seconds;
public ProducerConsumer(int producerNumber, int consumerNumber, int bufferSize, int seconds) {
this.producerNumber = producerNumber;
this.consumerNumber = consumerNumber;
this.bufferSize = bufferSize;
this.seconds = seconds;
System.out.println(this.producerNumber+ ": the number of producer threads");
System.out.println(this.consumerNumber+ ": the number of consumer threads");
System.out.println(this.bufferSize+ ": the number of producer threads");
}
public void process() throws InterruptedException {
ExecutorService producerExecutorService = Executors.newFixedThreadPool(this.producerNumber);
ExecutorService consumerExecutorService = Executors.newFixedThreadPool(this.consumerNumber);
BlockingQueue<Integer> integers = new ArrayBlockingQueue<Integer>(this.bufferSize);
for (int i = 0; i < this.producerNumber; i++) {
producerExecutorService.execute(new ProducerTask(integers));
}
for (int i = 0; i < this.consumerNumber; i++) {
consumerExecutorService.execute(new ConsumerTask(integers));
}
producerExecutorService.shutdown();
consumerExecutorService.shutdown();
//let the program run 10 seconds
producerExecutorService.awaitTermination(this.seconds, TimeUnit.SECONDS);
consumerExecutorService.awaitTermination(this.seconds, TimeUnit.SECONDS);
}
private class ProducerTask implements Runnable {
private final BlockingQueue<Integer> integers;
public ProducerTask(BlockingQueue<Integer> integers) {
this.integers = integers;
}
public void run() {
while (true) {
Integer content = new SecureRandom().nextInt(1000);
System.out.println("Producer #" + Thread.currentThread().getId() + " put: " + content);
integers.offer(content);
try {
Thread.sleep(new SecureRandom().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private class ConsumerTask implements Runnable {
private final BlockingQueue<Integer> integers;
public ConsumerTask(BlockingQueue<Integer> integers) {
this.integers = integers;
}
public void run() {
while (true) {
try {
System.out.println("Consumer #" + Thread.currentThread().getId() + " get: " + integers.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(new SecureRandom().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
import org.junit.Test;
/**
* Created by Leon.H on 2016/1/13.
*/
public class ProducerConsumerTest {
#Test
public void oneProducerOneConsumerSizeOne() throws InterruptedException {
int ProducerNumber = 1;
int ConsumerNumber = 1;
int size = 1;
int seconds=5;
ProducerConsumer producerConsumer = new ProducerConsumer(ProducerNumber, ConsumerNumber, size, seconds);
producerConsumer.process();
}
#Test
public void twoProducerThreeConsumerSizeThree() throws InterruptedException {
int ProducerNumber = 2;
int ConsumerNumber = 3;
int size = 3;
int seconds = 5;
ProducerConsumer producerConsumer = new ProducerConsumer(ProducerNumber, ConsumerNumber, size, seconds);
producerConsumer.process();
}
#Test
public void twoHundredProducerThreeConsumerSizeThree() throws InterruptedException {
int ProducerNumber = 20;
int ConsumerNumber = 3;
int size = 3;
int seconds=5;
ProducerConsumer producerConsumer = new ProducerConsumer(ProducerNumber, ConsumerNumber, size, seconds);
producerConsumer.process();
}
}

Related

Semaphore in Java. producer-consumer problem

I am testing the use of semaphores with the typical producer-consumer problem where I only have one producer and one consumer. The producer adds products one at a time and the consumer can withdraw several simultaneously.
To perform the test, the producer and the consumer store and remove numbers from a array of 10 elements where 0 represents that there are no products and any other number represents a product. Access to store and retrieve items is centralized in a class called Data. I use a mutex to make an orderly use of the vector in case we have more than one thread working simultaneously.
When executing it, I observe that the number of permissions is not correct according to the operations performed by the threads. The application shows an error because the semaphore of the producer says that it has permission, but the data vector is full.
package producer.consumer;
import java.io.IOException;
public class ProducerConsumer {
public static void main(String[] args) throws IOException {
final int MAX = 10;
Data data = new Data(MAX);
Consumer consumer = new Consumer(data);
Producer producer = new Producer(data);
consumer.start();
producer.start();
}
}
package producer.consumer;
public class Producer extends Thread{
private final Data data;
public Producer(Data data) {
this.data = data;
}
#Override
public void run() {
while (true) {
try {
data.add((int) (Math.random() * data.getLength()) + 1);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
}
}
}
package producer.consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Consumer extends Thread{
private final Data data;
public Consumer(Data data) {
this.data = data;
}
#Override
public void run() {
while (true) {
try {
data.remove((int) (Math.random() * data.getLength()) + 1);
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
package producer.consumer;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.Semaphore;
public class Data {
private final int[] data;
private final Semaphore mutex = new Semaphore(1);
private final Semaphore semProducer, semConsumer;
public Data(int MAX) throws IOException {
data = new int[MAX];
semProducer = new Semaphore(MAX);
semConsumer = new Semaphore(0);
}
public int getLength() {
return data.length;
}
public void add(int number) throws InterruptedException {
semProducer.acquire();
mutex.acquire();
System.out.println("trying to add a product");
int i = 0;
while (data[i] != 0) {
i++;
}
data[i] = number;
int permits = semConsumer.availablePermits() + 1;
System.out.println("data added in " + i + " " + Arrays.toString(data)
+ " Resources consumer " + permits
+ " Resources producer " + semProducer.availablePermits());
mutex.release();
semConsumer.release();
}
public void remove(int numberElements) throws InterruptedException {
semConsumer.acquire(numberElements);
mutex.acquire();
System.out.println("trying to withdraw " + numberElements);
for (int i = 0; i < numberElements; i++) {
if (data[i] != 0) {
data[i] = 0;
}
}
int permisos = semProducer.availablePermits() + 1;
System.out.println(" Retired " + numberElements + " " + Arrays.toString(data)
+ " Resources consumer " + semConsumer.availablePermits()
+ " Resources producer " + permisos);
mutex.release();
semProducer.release(numberElements);
}
}
Thank you very much for the help.
Your consumer does not always consume what it claims to consume.
for (int i = 0; i < numberElements; i++) {
if (data[i] != 0) {
data[i] = 0;
}
}
Suppose numberElements is 3, and that we have exactly 3 available elements in data[7], data[8], data[9].
The loop terminates with i == 3, nothing has been removed, but the producer semaphore will still be 'upped' by 3.
In the consumer, if you use i as the array index, it needs to cover the whole array, and you need a separate counter for 'elements removed'.
It is not the case that available elements will always be in the lowest-numbered data slots even though the producer fills those in first. Consider the time sequence that the producer manages to produce at least 5 elements, then the consumer runs to consume 2, and then immediately runs again to consume 3, before any more have been produced. data[0] and data[1] will be empty on the second run of the consumer and we run into the scenario I describe.
EDIT Acquiring and releasing permits seems correct; but you need to make sure that the consumer will actually clear the correct number of elements.
In example, edit the Data class with
public void remove(int numberElements) throws InterruptedException {
semConsumer.acquire(numberElements);
mutex.acquire();
System.out.println("remove: num-elem=" + numberElements);
int consumed=0;
for (int i = 0; consumed<numberElements; i++) {
if (data[i] != 0) {
data[i] = 0;
consumed++;
}
}
System.out.println(
" Retired " + numberElements + " " + Arrays.toString(data) );
mutex.release();
semProducer.release(numberElements);
}
Note also that this implementation is not very efficient (you'll need to iterate over the whole array both when inserting and deleting items, which can be expensive when MAX is large..)

Java multi-threading example printing message 100 times on different threads?

I'm tracing this code and I'm trying to figure out what exactly it's supposed to do. I can't get it running on IntelliJ. The run option is greyed out even though I defined the Project SDK. But I just want to know what the code is supposed to do.
I just read a bit of theory on threads. Is it just supposed to display each message 100 times with a timestamp on different threads? And Runnable 4 is an example of how to do it with a lambda correct?
Main class
import java.util.Date;
import java.util.concurrent.*;
public class Example02
{
public static void main(String []args)
{
// create runnables
PrintMessageRunnable pmRunnable1 = new PrintMessageRunnable("Runnable 1");
PrintMessageRunnable pmRunnable2 = new PrintMessageRunnable("Runnable 2");
PrintMessageRunnable pmRunnable3 = new PrintMessageRunnable("Runnable 3");
// passing a runnable using Lambda notation
Runnable pmRunnable4 = () -> {
// this is the code inside the run method
String message = "Lambda Runnable";
int REPETITIONS = 100;
int DELAY = 100;
try {
for(int i = 1; i <= REPETITIONS; i++) {
Date now = new Date();
System.out.println(now + ": " + message + "." + i);
Thread.sleep(DELAY);
}
}
catch (InterruptedException e) {
System.out.println("Runnable version interrupted.");
}
};
// specify how many threads the executor service should manage
int MAX_THREADS = 2;
ExecutorService pool = Executors.newFixedThreadPool(MAX_THREADS);
// start running
pool.execute(pmRunnable1);
pool.execute(pmRunnable2);
pool.execute(pmRunnable3);
pool.execute(pmRunnable4);
}
}
Print Message Runnable class
import java.util.*;
public class PrintMessageRunnable implements Runnable
{
private String message;
private int REPETITIONS = 100;
private int DELAY = 100;
public PrintMessageRunnable(String message){
this.message = message;
}
public void run(){
try {
for(int i = 1; i <= REPETITIONS; i++) {
Date now = new Date();
System.out.println(now + ": " + message + "." + i);
Thread.sleep(DELAY);
}
}
catch (InterruptedException e) {
System.out.println("Runnable version interrupted.");
}
}
}
In your example you have 2 threads which prints your message with a timestamp.
The lambda presentation of runnable is correct too.
But the usage of java.util.Date is dangerous, bacause of it isn't threadsafe.
Use LocalDateTime in multithread application to avoid errors

Multi thread is slower than one [duplicate]

This question already has answers here:
Java: How to use Thread.join
(3 answers)
Closed 8 years ago.
I am writing application using multi threads to count number of char inside txt file.
File contains 10 000 000 chars. 10 000 rows and 1 000 columns.
EDITED
About first part of the question:
Prevoius questions was about threads, I used a thread.join(); in wrong way.
Second part:
Could you help me improve the performance and safety? Here is my code (Use of the Semaphore is required):
public class MultiThread implements Runnable {
HashMap<String, AtomicInteger> asciiMap = Maps.newHashMap();
LinkedList<String> asciiLines = ReadDataFromFile.lines;
Semaphore mutex = new Semaphore(1);
AtomicInteger i = new AtomicInteger(0);
int index;
#Override
public void run() {
long actual = 0;
try {
Calculate calculate = new Calculate();
long multiStart = System.currentTimeMillis();
Thread first = new Thread(calculate);
Thread second = new Thread(calculate);
Thread third = new Thread(calculate);
first.start();
second.start();
third.start();
first.join();
second.join();
third.join();
long multiEnd = System.currentTimeMillis();
actual = multiEnd - multiStart;
} catch (InterruptedException ex) {
Logger.getLogger(MultiThread.class.getName()).log(Level.SEVERE, null, ex);
}
int sum = 0;
for (Map.Entry<String, AtomicInteger> entry : asciiMap.entrySet()) {
System.out.println("Char: " + entry.getKey() + " , number: " + entry.getValue());
sum = sum + entry.getValue().get();
}
System.out.println("Time: " + actual);
}
int increment() {
try {
mutex.acquire();
index = i.incrementAndGet();
mutex.release();
} catch (InterruptedException ex) {
Logger.getLogger(MultiThread.class.getName()).log(Level.SEVERE, null, ex);
}
return index;
}
public class Calculate implements Runnable {
public Calculate() {
}
#Override
public void run() {
while (i.get() < asciiLines.size()) {
for (String oneCharacter : asciiLines.get(i.get()).split("")) {
if (asciiMap.containsKey(oneCharacter)) {
asciiMap.replace(oneCharacter, new AtomicInteger(asciiMap.get(oneCharacter).incrementAndGet()));
} else {
asciiMap.put(oneCharacter, new AtomicInteger(1));
}
}
i = new AtomicInteger(increment());
}
}
}
}
Every element inside LinkedList contains one row (1 000 chars).
Your code does absolutely no multithreading. Thread.join means wait until that thread has finished executing, then continue the current thread of execution. Right now, your code is executing each thread serially. You want to interleave your calls to start and join.
Thread first = new Thread(calculate);
Thread third = new Thread(calculate);
Thread second = new Thread(calculate);
first.start();
second.start();
third.start();
first.join();
second.join();
third.join();

Write a program using java threads to print the following sequence 2 3 4 6 6 9 8 12 10 (Multiple of 2 and 3 in a sequence)

Basically what it does is that it prints the following numbers multiple of 2 and 3 in sequence like this
2 3 4 6 6 9 8 12 10 = this is the output
(2*1=2) (3*1=3) (2*2=4) (3*2=6) (2*3=6) (3*3=9) (2*4=8) (3*4=12) (2*5=10) = just a guide
here's my code so far, I'm having trouble displaying it in sequence. I've tried using wait and notify but it's a mess. So far this one is working.
public class Main {
public static void main(String[] args) throws InterruptedException {
final Thread mulof2 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
int n = 2;
int result = n * i;
System.out.print(result + " ");
}
}
};
Thread mulof3 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
int n = 3;
int result = n * i;
System.out.print(result + " ");
}
}
};
mulof2.start();
mulof3.start();
}
}
With Java 7 your first choice should be a Phaser. You'll only need one instance of it, created with new Phaser(1). You'll need just two methods for coordination: arrive and awaitAdvance.
Multiplication Table in java using Threads Concept
public class Multiplication extends Thread {
public void run() {
for (int i = 1; i < 10; i++) {
int n = 2;
int result = n * i;
System.out.print(i+"*"+n+"="+result+"\n");
}
}
public static void main(String[] args) throws InterruptedException {
Multiplication mul=new Multiplication();
mul.start();
}
}
Instead of printing during computation, you can aggregate the results into strings and then print both strings in order. After joining with the threads of course.
wait() and notify() are generally too low level, and too complex to use. Try using a more high-level abstraction like Semaphore.
You could have a pair of Semaphore instances: one which allows printing the next multiple of 2, and another one which allows printing the next multiple of 3. Once the next multiple of 2 has been printed, the thread should give a permit to print the next multiple of 3, and vice-versa.
Of course, the initial numbers of permits of the semaphores must be 1 for the multiple-of-2 semaphore, and 0 for the other one.
A simple modification would help you get the required sequence.
You need to declare a semaphore as other have pointed out private Semaphore semaphore;. Then declare another variable to denote which thread has to execute next such as private int threadToExecute; .
Next step is within your thread execute the code between semaphore.acquire(); and semaphore.release();
thread2:
try{
semaphore.acquire();
if(threadToExecute ==2)
semaphore.release();
//write your multiply by 2 code here
threadToExecute = 3;
semaphore.release();
}catch(Exception e){
//exceptions
}
This will nicely synchronize your output.
Below is the code that will give you desired results.
public class Main {
public static void main(String[] args) throws InterruptedException {
final Object lock1 = new Object();
final Object lock2 = new Object();
final Thread mulof2 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (lock1) {
synchronized (lock2) {
lock2.notify();
int n = 2;
int result = n * i;
printResult(result);
}
try {
lock1.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread mulof3 = new Thread(){
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (lock2) {
synchronized (lock1) {
lock1.notify();
int n = 3;
int result = n * i;
printResult(result);
}
try {
lock2.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
mulof2.start();
mulof3.start();
}
static void printResult(int result)
{
try {
// Sleep a random length of time from 1-2s
System.out.print(result + " ");
Thread.sleep(new Random().nextInt(1000) + 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Distributing each thread a Particular Range

I am using ThreadPoolExecutor in my multithreading program, I want each thread should have particular range of ID's if ThreadSize is set as 10 and Start = 1 and End = 1000 then each thread would have range of 100 id's(basically by dividing end range with thread size) that it can use without stepping on other threads.
Thread1 will use 1 to 100 (id's)
Thread2 will use 101 to 200 (id's)
Thread3 will use 201 to 300 (id's)
-----
-----
Thread10 will use 901 to 1000
I know the logic basically, the logic can be like this-
Each thread gets `N = (End - Start + 1) / ThreadSize` numbers.
Thread number `i` gets range `(Start + i*N) - (Start + i*N + N - 1)`.
As I am working with ThreadPoolExecutor for the first time, so I am not sure where should I use this logic in my code so that each Thread is Using a predefined ID's without stepping on other threads. Any suggestions will be appreciated.
public class CommandExecutor {
private List<Command> commands;
ExecutorService executorService;
private static int noOfThreads = 3;
// Singleton
private static CommandExecutor instance;
public static synchronized CommandExecutor getInstance() {
if (instance == null) {
instance = new CommandExecutor();
}
return instance;
}
private CommandExecutor() {
try {
executorService = Executors.newFixedThreadPool(noOfThreads);
} catch(Exception e) {
System.out.println(e);
}
}
// Get the next command to execute based on percentages
private synchronized Command getNextCommandToExecute() {
}
// Runs the next command
public synchronized void runNextCommand() {
// If there are any free threads in the thread pool
if (!(((ThreadPoolExecutor) executorService).getActiveCount() < noOfThreads))
return;
// Get command to execute
Command nextCommand = getNextCommandToExecute();
// Create a runnable wrapping that command
Task nextCommandExecutorRunnable = new Task(nextCommand);
executorService.submit(nextCommandExecutorRunnable); // Submit it for execution
}
// Implementation of runnable (the real unit level command executor)
private static final class Task implements Runnable {
private Command command;
public Task(Command command) {
this.command = command;
}
public void run() {
// Run the command
command.run();
}
}
// A wrapper class that invoked at every certain frequency, asks CommandExecutor to execute next command (if any free threads are available)
private static final class CoreTask implements Runnable {
public void run() {
CommandExecutor commandExecutor = CommandExecutor.getInstance();
commandExecutor.runNextCommand();
}
}
// Main Method
public static void main(String args[]) {
// Scheduling the execution of any command every 10 milli-seconds
Runnable coreTask = new CoreTask();
ScheduledFuture<?> scheduledFuture = Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(coreTask, 0, 10, TimeUnit.MILLISECONDS);
}
}
Whether this is a good idea or not I will leave it for you to decide. But to give you a hand, I wrote a little program that does what you want... in my case I am just summing over the "ids".
Here is the code:
public class Driver {
private static final int N = 5;
public static void main(String args[]) throws InterruptedException, ExecutionException{
int startId = 1;
int endId = 1000;
int range = (1 + endId - startId) / N;
ExecutorService ex = Executors.newFixedThreadPool(N);
List<Future<Integer>> futures = new ArrayList<Future<Integer>>(N);
// submit all the N threads
for (int i = startId; i < endId; i += range) {
futures.add(ex.submit(new SumCallable(i, range+i-1)));
}
// get all the results
int result = 0;
for (int i = 0; i < futures.size(); i++) {
result += futures.get(i).get();
}
System.out.println("Result of summing over everything is : " + result);
}
private static class SumCallable implements Callable<Integer> {
private int from, to, count;
private static int countInstance = 1;
public SumCallable(int from, int to) {
this.from = from;
this.to = to;
this.count = countInstance;
System.out.println("Thread " + countInstance++ + " will use " + from + " to " + to);
}
// example implementation: sums over all integers between from and to, inclusive.
#Override
public Integer call() throws Exception {
int result = 0;
for (int i = from; i <= to; i++) {
result += i;
}
System.out.println("Thread " + count + " got result : " + result);
return result;
}
}
}
which produces the following output (notice that in true multi-thread fashion, you have print statements in random order, as the threads are executed in whatever order the system decides):
Thread 1 will use 1 to 200
Thread 2 will use 201 to 400
Thread 1 got result : 20100
Thread 3 will use 401 to 600
Thread 2 got result : 60100
Thread 4 will use 601 to 800
Thread 3 got result : 100100
Thread 5 will use 801 to 1000
Thread 4 got result : 140100
Thread 5 got result : 180100
Result of summing over everything is : 500500

Categories

Resources