How to execute Runnable/Thread in correct sequence - java

Imagine a datastream like this
A,A,B,A,C,C,C,A,B,A,A,A,B...
Now lets assume we have a StreamProcessor that will handle the stream. We can process A,B,C in parallel but individual As,Bs,Cs have to be processed in sequence.
Example:
Thread 1: Processes all As in sequence
Thread 2: Processes all Bs in sequence
and so on...
So for A,B,C I have a StreamProcessor (SP).
Each of the stream elements has a timestamp and thus can be ordered by time (It actually comes in the correct sequence). The elements have to be processed in time sequence.
So now I split up all my stream elements to their processors (SPA,SPB,SPC).
I have a TreeSet in ever SP where I add the elements.
So whenever there is a new element I basically do this:
public synchronized void onNewElementReceived(Element element) {
if (element== null) return;
treeSet.add(element);
if(treeSet.size()>30) logger.warn("There are many elements queueing up for processing");
threadPool.execute(() -> process(treeSet.first()));
}
private synchronized void process(Element element){
//Do the processing
}
This works fine if the stream is slow enough for process to terminate before there is the next element. But what if not? If there are more elements coming how can I make sure that the next element also is the next element that is going to be processed? In the end the operating system decides which Thread is fired when?
Edit: For clarity an example where this will fail:
Assume process() of A elements takes 1 second to execute. Now if the stream provides As faster then we can process them our treeSet will fill with elements of type A (I just realized it does not because we immediatly fetch it again, hmm another problem) anyway the main problem stays. If we receive elements every 100 ms for example we would request 10 executions of the process method, but the order would not be guaranteed anymore, because we do not know, which Runnable is going to be executed first by the system. We only ADDED them in the correct sequence but how to EXECUTE them in the correct sequence?
I could imagine just running a looper thread all the time fetching the first element of the queue and if there is none abort the process. Is that a good approach?

I would do it like this (PseudoCode-Like):
abstract class StreamProcessor extends Thread{
private ThreadSafeList<Element> elements;
void add(Element e) {
elements.addAtEnd(e);
}
#Override
public void run() {
while(hasNotFinished()) {
//If list has element, return the first element and remove it from the list, otherwise block until one is there and then return the first element and remove it.
Element e = elements.blockingRemoveFirst();
this.workWith(e);
}
}
abstract void workWith(Element e);
}
class StreamProcessorA extends StreamProcessor {
#Override
public void workWith(Element e) {
//Do something
}
}
class StreamProcessorB extends StreamProcessor {
#Override
public void workWith(Element e) {
//Do something
}
}
class StreamProcessorC extends StreamProcessor {
#Override
public void workWith(Element e) {
//Do something
}
}
class ElementReceiver {
private StreamProcessor A;
private StreamProcessor B;
private StreamProcessor C;
public synchronized void onNewElementReceived(Element e) {
if(e.type() /*Whatever*/ == ElementType.A) {
A.add(e);
}else if(e.type() == ElementType.B) {
B.add(e);
}else {
C.add(e);
}
}
}
This code consists of four threads.
The first thread receives the Element from some unspecified data source.
If this thread receives one, it checks what type it is (A,B or C).
Each of these types has a corresponding StreamProcessor. The onNewElementReceived will add the received element to the working set of the corresponding StreamProcessor.
Each of these StreamProcessor threads checks until they are for example killed and blocks until it has got an Element and then the method workWith is called that has to be implemented by each subclass.

Related

Consumer-Producer with Threads and BlockingQueues

I wrote a Class 'Producer' which is continuously parsing files from a specific folder. The parsed result will be stored in queue for the Consumer.
public class Producer extends Thread
{
private BlockingQueue<MyObject> queue;
...
public void run()
{
while (true)
{
//Store email attachments into directory
...
//Fill the queue
queue.put(myObject);
sleep(5*60*1000);
}
}
}
My Consumer Class is continuously checking if there is something available in the queue. If so, it's performing some work on the parsed result.
public class Consumer extends Thread
{
private BlockingQueue<MyObject> queue;
...
public void run()
{
while (true)
{
MyObject o = queue.poll();
// Work on MyObject 'o'
...
sleep(5*60*1000);
}
}
}
When I run my programm, 'top' shows that the JAVA process is always on 100%. I guess it's because of the infinite loops.
Is this a good way to implement this or is there a more resource saving way for doing this?
Instead of
MyObject o = queue.poll();
try
MyObject o = queue.take();
The latter will block until there is something available in the queue, whereas the former will always return immediately, whether or not something is available.

java multi threading - how to synchronise

I have a class with following method
public class Test {
private List l1;
public void send() {
for (<type> x : l1) {
//send to receivers and put a log in DB
}
}
}
This Test class is used by different threads which will fill the variable 'l1' with their own data and send them to receivers.
If I have to synchronize this to send data sequentially so that receivers get one full frame of data every time(without jumbling of data from different threads), should I synchronize on 'l1' or synchronize on the class Test.
I read the tutorials and samples but I still have this question.
You should synchronize on the object that represents you "shared state" (l1 in this case); you must ensure that every insert/read operation is synchronized
so you must have a synchronized(l1) {...} block for add (and remove) call and one while sending:
public void send() {
synchronized(l1) {
for (<type> x : l1) {
//send to receivers and put a log in DB
}
}
}
depending on you requirements you can also implement something more complex like:
public void send() {
synchronized(l1) {
List l2=new ArrayList(l1);
//clear l1?
}
for (<type> x : l2) {
//send to receivers and put a log in DB
}
}
and allow a grater degree of concurrency

Notify multiple threads periodically

I'm working on a project that uses primitive Java concurrent structures such as wait(), notify(), notifyAll(), Thread.run(), synhronized etc.
On my project, there are multiple threads (a extension of Thread class) who will get an object from a queue periodically. Thus, I use a Timer class which has an inner TimerTask class.
My problem is that, I could not get how to make other threads wake up periodically. My main class is not these threads or timer classes. Thus I call their run from another class. I could not figure out how to make these threads wait and notify for one time per 100 miliseconds. My timer class is:
public class Controller extends Timer{
int counter;
TimerTask task;
final Controller c = this;
public class PeriodicTime extends TimerTask {
#Override
public void run() {
if(counter > 0) {
//do some stuff to wake up threads
}
counter++;
}
}
Controller () {
super ();
this.task = new PeriodicTime();
counter = 0;
this.schedule(task, 300, 100);
}
}
And my thread class is:
public class Element extends Thread {
public void run() {
// do something to get an object from another class (a queue)
}
}
Now, i'm really confused how to make periodic releasing to the thread class. I even could not get whether to use wait()/notify() or not.
As I told before, i'll create multiple Element class. They will work synchronized. Then, what should I do?
Make a list of Objects that will represent mutexes, Each Element thread will get one mutex from the list, while the timer task gets the list.
TimerTask calls notify() on every mutex object when the time period expires. This wakes up the Element threads.
Element threads process data from queue and when they are done they each call wait() on their mutex object.
Now you need thread safety built into the queue since there are multiple consumers, but not the blocking logic since it is handled by the TimerTask.
Also, if I understood you correctly, you want Elements put something back to queue as they process the data. For that you can use an auxilary queue that you can drain into the first one after elements are done or you can just swap them (This is done by TimerTask and requires an atomic counter that will get incremented when Element wakes up and decremented when it goes to sleep). Alternatively, you can use a "stop" value that you can put into queue just before you wake up Elements, and make them work until they reach it. For N element threads you would need to put N stop values so all of them get the message.
How to use mutexes:
List<Object> mutexList;
//initialize the list with plain Objects. You just need them to be separate instances.
....
//When creating Element threads add one object from the list to each Element.
....
//in Element code
public class Element extends Thread {
//This is one element from the list
private Object mutex;
public void run() {
// do something to get an object from another class (a queue)
//....
synchronized(mutex){
mutex.wait();
}
}
}
// in timerTask code
public class PeriodicTime extends TimerTask {
List<Object> mutexList;
#Override
public void run() {
if(counter > 0) {
//do some stuff to wake up threads
for(Object mutex:mutexList){
mutex.notify();
}
}
counter++;
}
}

Java - Multiple queue producer consumer

I've got the following code:
while(!currentBoard.boardIsValid()){
for (QueueLocation location : QueueLocation.values()){
while(!inbox.isEmpty(location)){
Cell c = inbox.dequeue(location);
notifyNeighbours(c.x, c.y, c.getCurrentState(),previousBoard);
}
}
}
I've got a consumer with a few queues (all of their methods are synchronised). One queue for each producer. The consumer loops over all the queues and checks if they've got a task for him to consume.
If the queue he's checking has a task in it, he consumes it. Otherwise, he goes to the check the next queue until he finishes iterating over all the queues.
As of now, if he iterates over all the queues and they're all empty, he keeps on looping rather than waiting for one of them to contain something (as seen by the outer while).
How can I make the consumer wait until one of the queues has something in it?
I'm having an issue with the following scenario: Lets say there are only 2 queues. The consumer checked the first one and it was empty. Just as he's checking the second one (which is also empty), the producer put something in the first queue. As far as the consumer is concerned, the queues are both empty and so he should wait (even though one of them isn't empty anymore and he should continue looping).
Edit:
One last thing. This is an exercise for me. I'm trying to implement the synchronisation myself. So if any of the java libraries have a solution that implements this I'm not interested in it. I'm trying to understand how I can implement this.
#Abe was close. I would use signal and wait - use the Object class built-ins as they are the lightest weight.
Object sync = new Object(); // Can use an existing object if there's an appropriate one
// On submit to queue
synchronized ( sync ) {
queue.add(...); // Must be inside to avoid a race condition
sync.notifyAll();
}
// On check for work in queue
synchronized ( sync ) {
item = null;
while ( item == null ) {
// Need to check all of the queues - if there will be a large number, this will be slow,
// and slow critical sections (synchronized blocks) are very bad for performance
item = getNextQueueItem();
if ( item == null ) {
sync.wait();
}
}
}
Note that sync.wait releases the lock on sync until the notify - and the lock on sync is required to successfully call the wait method (it's a reminder to the programmer that some type of critical section is really needed for this to work reliably).
By the way, I would recommend a queue dedicated to the consumer (or group of consumers) rather than a queue dedicated to the producer, if feasible. It will simplify the solution.
If you want to block across multiple queues, then one option is to use java's Lock and Condition objects and then use the signal method.
So whenever the producer has data, it should invoke the signallAll.
Lock fileLock = new ReentrantLock();
Condition condition = fileLock.newCondition();
...
// producer has to signal
condition.signalAll();
...
// consumer has to await.
condition.await();
This way only when the signal is provided will the consumer go and check the queues.
I solved a similar situation along the lines of what #Abe suggests, but settled on using a Semaphore in combination with an AtomicBoolean and called it a BinarySemaphore. It does require the producers to be modified so that they signal when there is something to do.
Below the code for the BinarySemaphore and a general idea of what the consumer work-loop should look like:
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class MultipleProdOneConsumer {
BinarySemaphore workAvailable = new BinarySemaphore();
class Consumer {
volatile boolean stop;
void loop() {
while (!stop) {
doWork();
if (!workAvailable.tryAcquire()) {
// waiting for work
try {
workAvailable.acquire();
} catch (InterruptedException e) {
if (!stop) {
// log error
}
}
}
}
}
void doWork() {}
void stopWork() {
stop = true;
workAvailable.release();
}
}
class Producer {
/* Must be called after work is added to the queue/made available. */
void signalSomethingToDo() {
workAvailable.release();
}
}
class BinarySemaphore {
private final AtomicBoolean havePermit = new AtomicBoolean();
private final Semaphore sync;
public BinarySemaphore() {
this(false);
}
public BinarySemaphore(boolean fair) {
sync = new Semaphore(0, fair);
}
public boolean release() {
boolean released = havePermit.compareAndSet(false, true);
if (released) {
sync.release();
}
return released;
}
public boolean tryAcquire() {
boolean acquired = sync.tryAcquire();
if (acquired) {
havePermit.set(false);
}
return acquired;
}
public boolean tryAcquire(long timeout, TimeUnit tunit) throws InterruptedException {
boolean acquired = sync.tryAcquire(timeout, tunit);
if (acquired) {
havePermit.set(false);
}
return acquired;
}
public void acquire() throws InterruptedException {
sync.acquire();
havePermit.set(false);
}
public void acquireUninterruptibly() {
sync.acquireUninterruptibly();
havePermit.set(false);
}
}
}

How to Thread a complex Model class to provide synchronization with a Controller class?

How can I proceed in a controller based on whether just one part of a complex model has produced the correct flag?
A controller class is playing a queue of Midi sequences while holding onto an instance of a model class that is dynamically updated via user button presses. After the Midi queue ends, the controller needs to synchronize with the model to check that the user has made a certain number of entries before proceeding to update the interface and move to the next part of the application. The Model represents quite a lot of other data in addition to the ArrayList of user button presses, so the challenge is how to best compartmentalize the synchronization part.
Right now, the pattern I'm trying is something like the following, which doesn't work because of nested class access between the controller and the model:
//Controller
...
Thread entriesCoordination = new Thread( new Model.InnerClass);
entriesCoordination.start();
Thread t = new Thread (this);
t.run();
...
//in runnable nested class in controller
private Model.InncerClass c = new Model.InnerClass();
public void run() {
synchronized( c) {
while (!c.hasFinishedEntries()){
try{
c.wait();
} catch (InterruptedException ignore{}
}
}
}
//Midiqueue completed and Entries finished
}
//in Model
//in runnable nested class in Model
public synchronized boolean hasFinishedEntries() {
return fIsFinishedWithEntries;
}
public void run() {
while(true) {
try{
synchronized(this) {
try{
if(entriesArray.size() == max_size) {
fIsFinishedWithEntries = true;
notifyAll();
} else {...}
}
}
}
}
}
Furthermore, this seems wasteful because it basically means that I need to create a thread and run the inner class of the Model in parallel the entire duration of the time that the user can make these button selections, rather than something that would just poll the Model when I know that the Midi queue has ended.
What's the design pattern to synchronize to one flag in a Model class from a Controller class without having to make a inner class in the model just to handle the synchronization.
I think the right thing to do here is to use an AtomicBoolean and define methods on each of your thread objects to get and set the boolean.
The Model.InnerClass would be changed to add the AtomicBoolean and to change the getter to not be synchronized.
private final AtomicBoolean fIsFinishedWithEntries = new AtomicBoolean();
public boolean hasFinishedEntries() {
return fIsFinishedWithEntries.get();
}
In the run method it something needs to set the finished boolean to be true.
public void run() {
while(true) {
if (entriesArray.size() == max_size) {
synchronized (this) {
fIsFinishedWithEntries.set(true);
notifyAll();
}
} else {...}
}
}
}
You'll need to rest it to false somewhere if you are doing this more than once.
Right now, the pattern I'm trying is something like the following, which doesn't work because of nested class access between the controller and the model:
You need to first create your Model.InnerClass instance and inject that into your controller thread. Making the hasFinishedEntries() be static is ugly so instead in your controller you'd call:
private Model.InnerClass innerClass;
public ControllerThread(Model.InnerClass innerClass) {
this.innerClass = innerClass;
}
...
public void run() {
synchronized (innerClass) {
while (!innerClass.hasFinishedEntries()){
innerClass.wait();
}
}
}
How can I access whether the entries are finished without synchronizing on the entire Model class?
You can obviously just poll the hasFinishedEntries() whenever you want to see if the queue has ended. I'm not sure of a better way to do this without a thread. Is there some way to setup a UI event which checks for a condition every so often?

Categories