This question already has answers here:
From Arraylist to Array
(11 answers)
Closed 6 months ago.
I should create Thread as ProducerThread and ConsumerThread those execute sequentially and put elements to queue. In this implementation I used ArrayList.
How might I convert an ArrayList object to integer Array in java.
This is my ConsumerThread class.
import java.util.ArrayList;
public class ConsumerThread implements Runnable {
ArrayList<Integer> queue = new ArrayList<Integer>();
public ConsumerThread(ArrayList<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
synchronized(queue) {
int value;
while(true) {
try {
queue.wait();
System.out.println("Consumer Started");
value = queue.remove(0);
System.out.println("Consumer thread consumes " + value);
System.out.println("Elements in Queue = " + queue);
Thread.sleep(1000);
queue.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
This is my ProducerThread class.
import java.util.ArrayList;
public class ProducerThread implements Runnable {
ArrayList<Integer> queue = new ArrayList<Integer>();
public ProducerThread(ArrayList<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
synchronized(queue) {
int value = 10;
while(true) {
try {
queue.notify();
System.out.println("Producer Started");
System.out.println("Producer adding value = " + value + " to Queue");
queue.add(value);
value = value + 10;
//Thread.sleep(1000);
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
This is my main class.
import java.util.ArrayList;
public class ThreadTest {
public static void main(String[] args) {
ArrayList<Integer> queue = new ArrayList<Integer>();
Thread producer = new Thread(new ProducerThread(queue));
Thread consumer = new Thread(new ConsumerThread(queue));
producer.start();
consumer.start();
System.out.println("Starting");
}
}
toArray() method convert any ArrayList to Array Objects -> Object[]
ArrayList<Integer> queue = new ArrayList<>();
queue.add(23);
queue.add(6765);
Object[] arrayQueue = queue.toArray();
System.out.println("arrayList = " + queue + "\n arrayNative = ");
Arrays.stream(arrayQueue).forEach(System.out::println);
Related
In the following code, I wrote producer-consumer with executor but I do not understand why when I call shutDownNow() the System.out.println(item) statement is executed twice. in fact, tryLock () returns the wrong value first, and then for the second time the item is printed and then it acquires the lock, and then the interrupt occurs.
public class Main {
public static void main(String[] args) {
Deque<String> queue = new ArrayDeque<>();
ReentrantLock bufferLock = new ReentrantLock();
Condition fullBuffer = bufferLock.newCondition();
MyProducer p = new MyProducer(queue, ThreadColor.ANSI_YELLOW, bufferLock, fullBuffer);
MyConsumer c1 = new MyConsumer(queue, ThreadColor.ANSI_BLUE, bufferLock, fullBuffer);
MyConsumer c2 = new MyConsumer(queue, ThreadColor.ANSI_BLUE, bufferLock, fullBuffer);
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.execute(p);
executorService.shutdownNow();
try {
executorService.execute(c1);
executorService.execute(c2);
} catch (RejectedExecutionException e) {
System.out.println("no new task has not accepted");
}
}
}
part of producer code:
public class MyProducer implements Runnable {
private final Deque<String> buffer;
private final String color;
private final ReentrantLock bufferLock;
private final Condition fullBuffer;
public MyProducer(Deque<String> buffer, String color, ReentrantLock bufferLock, Condition fullBuffer) {
this.buffer = buffer;
this.color = color;
this.bufferLock = bufferLock;
this.fullBuffer = fullBuffer;
}
#Override
public void run() {
String[] items = {"apple", "ball", "laptop", "mouse", "cup", "pc", "pencil", "pen"};
long start = System.currentTimeMillis();
for (String item : items) {
System.out.println(item);
try {
if (bufferLock.tryLock(1, TimeUnit.SECONDS)) {
try {
while (items.length == buffer.size()) {
try {
fullBuffer.await();
} catch (InterruptedException e) {
System.out.println(color + "Producer was interrupted");
}
}
System.out.println(color + "Adding:" + item);
try {
Thread.sleep(250);
} catch (InterruptedException e) {
System.out.println(color + "failed to add");
}
buffer.add(item);
fullBuffer.signalAll();
} finally {
bufferLock.unlock();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bufferLock.lock();
try {
buffer.add("EOF");
} finally {
bufferLock.unlock();
}
System.out.println(Thread.currentThread().getName() + ":" + (System.currentTimeMillis() - start) + " ms");
}
}
output image
I have a simple code, consisting of 4 threads (2 modify the data and 2 read the data). I just wrote this sample code to play around with Semaphor and I am not sure why I get ava.base/java.util.ArrayList$Itr.checkForComodification exception? Here are the source code and thanks for any insights.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static class InnerWriterSemaphoreThread implements Runnable {
private final List<String> fList;
private final Semaphore fWriteSem;
InnerWriterSemaphoreThread(List<String> list, Semaphore w) {
fList = list;
fWriteSem = w;
}
private void prune() {
System.out.println(Thread.currentThread().getName()+" in prune()..");
for (String s : fList) {
fList.remove(s);
}
}
#Override
public void run() {
String name = Thread.currentThread().getName();
String text;
while (true) {
text = RandomTextGenerator.getRandomSNumbertring();
try {
while(!fWriteSem.tryAcquire()){
System.out.println(name+" waiting to accquire semaphore to write..");
Thread.sleep(0L,4);
}
if (fList.size() > 10) {
prune();
}
fList.add(text);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
fWriteSem.release();// notify readers that write has completed
System.out.println(name+" finished writing, releasing semaphore..");
}
}//while()
}//run()
}//WriterSemaphoreThread
public static class InnerReaderSemaphoreThread implements Runnable {
private final List<String> fList;
private final Semaphore fWriteSem;
InnerReaderSemaphoreThread(List<String> list,Semaphore w) {
fList = list;
fWriteSem = w;
}
private void sleep(){
try{
Thread.sleep(0L, 4);
}catch(InterruptedException e){
e.printStackTrace();
}
}
#Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
System.out.println(name + " in run()..");
try {
while(fList.isEmpty()){
System.out.println(name+" list is empty, going to sleep..");
sleep();
}
while(!fWriteSem.tryAcquire()){
System.out.println(name+" waiting to accquire semaphor to read..");
Thread.sleep(0l,4);
}
for (String text : fList) {
System.out.println(name + " reading from list " + text);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
finally{
fWriteSem.release(); //Notify threads who want to write to the list
System.out.println(name+" finished reading, releasing semaphore and going to sleep..");
sleep();
}
}
}
}//ReaderSemaphoreThread
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Semaphore r = new Semaphore(1);
Thread th1 = new Thread(new InnerWriterSemaphoreThread(list, r), "Thread 1");
Thread th2 = new Thread(new InnerReaderSemaphoreThread(list, r), "Thread 2");
Thread th3 = new Thread(new InnerWriterSemaphoreThread(list, r), "Thread 3");
Thread th4 = new Thread(new InnerReaderSemaphoreThread(list, r), "Thread 4");
th2.start();
th4.start();
th1.start();
th3.start();
}
}
Above is the sample source code
As #assylias mentioned in comment it happens when you remove elements from list in foreach loop. Just replace
for (String s : fList) {
fList.remove(s);
}
with
fList.clear();
This question already has an answer here:
Why Java throw java.lang.IllegalMonitorStateException when I invoke wait() in static way synchronized block?
(1 answer)
Closed 2 years ago.
In the below code for producer and consumer, I thought that the produce() and consume() methods are synchronized on Class Lock (Processor.class), but i am getting an exception stating IllegalMonitorStateException, which occurs for objects on which we don't acquire lock but we notify on that objects.
Can anyone tell me where i have gone wrong in the program.
package ProducerConsumer;
public class Main {
public static void main(String[] args) {
Processor processor = new Processor();
Thread producer = new Thread(new Runnable() {
public void run() {
try {
processor.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumer = new Thread(new Runnable() {
public void run() {
try {
processor.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("\t\t\tStarting both producer and consumer Threads.");
producer.start();
consumer.start();
try {
producer.join();
consumer.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\t\t\tEnding all the Threads.");
}
}
import java.util.List;
import java.util.ArrayList;
public class Processor {
private List<Integer> list = new ArrayList<>();
private int value = 0;
private final int LIMIT = 5;
public void produce() throws InterruptedException
{
synchronized(Processor.class){
while(true)
{
if(list.size() == LIMIT){
System.out.println("Waiting for consumer to consume resources");
wait();
}
else{
value++;
System.out.println("The produced resource is : "+value);
list.add(value);
notify();
}
}
}
}
public void consume() throws InterruptedException
{
synchronized(Processor.class){
while(true)
{
if(list.isEmpty()){
System.out.println("Waiting for producer to produce the resources");
wait();
}
else{
System.out.println("The consumer Consumed Resource is : "+list.remove(0));
notify();
}
}
}
}
}
Your wait() & notify() are invoked on this i.e. Processor processor = new Processor(); but your are locking/synchronizing on Processor.class object. You can fix your code to work as below.
class Processor {
private List<Integer> list = new ArrayList<>();
private int value = 0;
private final int LIMIT = 5;
public void produce() throws InterruptedException
{
synchronized(Processor.class){
while(true)
{
if(list.size() == LIMIT){
System.out.println("Waiting for consumer to consume resources");
Processor.class.wait();
}
else{
value++;
System.out.println("The produced resource is : "+value);
list.add(value);
Processor.class.notify();
}
}
}
}
public void consume() throws InterruptedException
{
synchronized(Processor.class){
while(true)
{
if(list.isEmpty()){
System.out.println("Waiting for producer to produce the resources");
Processor.class.wait();
}
else{
System.out.println("The consumer Consumed Resource is : "+list.remove(0));
Processor.class.notifyAll();
}
}
}
}
}
I'm doing some courses on MultiThreading in Java. I've tried (following instructor) to synchronise two consumers reading from ArrayList with one producer filling it with some basic input. Yet producer gives first number and consumer gets in infinite loop because it gets empty List. No idea how to force it to get proper values.
Producer:
class MyProducer implements Runnable {
private List<String> buffer;
private String color;
public MyProducer(List<String> buffer, String color) {
this.buffer = buffer;
this.color = color;
}
public void run() {
Random random = new Random();
String[] nums = {"1", "2", "3", "4", "5"};
for(String num: nums) {
try {
System.out.println(color + "Adding..." + num);
synchronized (buffer) {
buffer.add(num);
System.out.println(buffer);
}
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
System.out.println("Producer was interrupted");
}
}
System.out.println(color + "Adding EOF and exiting...");
synchronized (buffer) {
buffer.add(EOF);
}
}
}
Consumer:
class MyConsumer implements Runnable {
private List<String> buffer;
private String color;
public MyConsumer(List<String> buffer, String color) {
this.buffer = buffer;
this.color = color;
}
public void run() {
synchronized (buffer) {
while(true) {
if (buffer.isEmpty()) {
continue;
}
System.out.println("Przejście między warunkami działa");
if (buffer.get(0).equals(EOF)) {
System.out.println(color + "Exiting");
break;
} else {
System.out.println(color + "Removed" + buffer.remove(0));
}
}
}
}
}
Main:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import static com.siecz-k-.Main.EOF;
public class Main {
public static final String EOF = "EOF";
public static void main(String[] args) {
List<String> buffer = new ArrayList<>();
MyProducer producer = new MyProducer(buffer, ThreadColor.ANSI_CYAN);
MyConsumer consumer1 = new MyConsumer(buffer, ThreadColor.ANSI_PURPLE);
MyConsumer consumer2 = new MyConsumer(buffer, ThreadColor.ANSI_RED);
new Thread(producer).start();
new Thread(consumer1).start();
new Thread(consumer2).start();
}
}
I am trying to write a producer consumer program in Java where producer inserts 3 numbers in a Queue and Consumer removes these numbers from the queue. I have implemented my own Queue based on my own Linkedlist implementation.
When I run my code my producer terminates but my consumer never terminates. I am not able to figure out why
public class ProdConMain {
public static void main(String[] args) throws InterruptedException {
MyQueue queue = new MyQueue();
queue.setLimit(3);
Thread producer = new Thread(new Producer(queue));
Thread consumer = new Thread(new Consumer(queue));
producer.start();
consumer.start();
try {
producer.join();
System.out.println("Producer: " + producer.getState());
consumer.join();
System.out.println("Consumer: " + consumer.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(queue.list.toString());
}
}
public class Producer implements Runnable {
MyQueue queue = new MyQueue();
Random random = new Random();
public Producer(MyQueue queue) {
this.queue = queue;
}
#Override
public void run() {
int i = 1;
while (i < 10) {
synchronized (queue) {
if (queue.getSize() < queue.getLimit()) {
int value = random.nextInt(500);
queue.enqueue(value);
System.out.println("Inserted: " + value);
queue.notify();
} else {
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
i++;
}
}
}
public class Consumer implements Runnable {
MyQueue queue = new MyQueue();
public Consumer(MyQueue queue) {
this.queue = queue;
}
#Override
public void run() {
while (true) {
synchronized (queue) {
if (queue.isEmpty()) {
{
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} else {
int value = queue.dequeue();
System.out.println("Removed: " + value);
queue.notify();
}
}
}
}
}
You need to add a stop condition to that while(true) loop in the consumer, otherwise it will never finish. You can do it in the while condition itself:
while(shouldConsume()) {
// consume ...
}
or by breaking the infinite loop if the condition is reached:
while(true) {
// consume ...
if (shouldStopConsume()) {
break;
}
}
And then you just have to implement those methods with the stop condition that fits your use case.