Weird bugs O_o
Fix 2 bugs:
1) an exception occurs
2) the program becomes unresponsive
Make minimal changes.
Requirements:
1. The startCreatingMessages() method must add 100000 elements to messageQueue without hanging.
2. Fix the bug in the line "messageQueue.drainTo(messageQueue, MAX_BATCH_SIZE);".
3. The main() method should not hang.
4. The program's output should show that all messages have been transferred from messageQueue to fakeDatabase.
package com.codegym.task.task29.task2905;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
Weird bugs O_o
*/
public class Solution {
final int NUMBER_OF_THREADS = 3; // 3 threads will process our queue
final int MAX_BATCH_SIZE = 100; // We'll pull out 100 messages each
private Logger logger = Logger.getLogger(Solution.class.getName());
private BlockingQueue messageQueue = new LinkedBlockingQueue(); // This is where all the messages will be stored
private BlockingQueue fakeDatabase = new LinkedBlockingQueue();
public static void main(String[] args) throws InterruptedException {
// Putting static modifiers all over the place is inappropriate, so we'll put all the data in fields,
// and then we'll create an object and call its methods
Solution solution = new Solution();
solution.startCreatingMessages();
solution.startPersistingMessages();
Thread.sleep(100);
solution.printResults();
Thread.sleep(100);
solution.printResults();
Thread.sleep(100);
solution.printResults();
Thread.sleep(500);
solution.printResults();
}
public void startCreatingMessages() {
new Thread() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
messageQueue.add(String.valueOf(i--));
}
}
}.start();
}
public void startPersistingMessages() {
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
new Thread() {
private final Collection batch = new ArrayList(MAX_BATCH_SIZE);
{
setDaemon(true);
}
@Override
public void run() {
while (true) {
try {
messageQueue.drainTo(messageQueue, MAX_BATCH_SIZE);
persistData(batch);
batch.clear();
Thread.sleep(1);
} catch (Throwable e) {
logger.log(Level.SEVERE, "Unable to persist batch", e);
}
}
}
}.start();
}
}
private void persistData(Collection batch) {
// Image that here we connect to a database and save the data in it
// Saving data one entry at a time uses a lot of resources, so we'll do in batches (several at a time)
fakeDatabase.addAll(batch);
}
private void printResults() {
System.out.println();
System.out.println("messageQueue size is " + messageQueue.size());
System.out.println("fakeDatabase size is " + fakeDatabase.size());
}
}