How does RecursiveAction work? - multithreading

I downloaded some existing code from internet. I ran it with few modifications. In one scenario, I did not get what I was looking for. Here is the code -
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class MyRecursiveAction extends RecursiveAction{
private long workload = 0;
public MyRecursiveAction(long workload) {
this.workload = workload;
}
#Override
protected void compute() {
if(this.workload > 16) {
System.out.println("Splitting workload :: " + this.workload);
List<MyRecursiveAction> subtasks = new ArrayList<MyRecursiveAction>();
subtasks.addAll(createSubtasks());
for(RecursiveAction subtask : subtasks) {
subtask.fork();
}
}else {
System.out.println("Doing work myself1 " + this.workload);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Done it ya " + this.workload);
}
}
private List<MyRecursiveAction> createSubtasks() {
List<MyRecursiveAction> subTasks = new ArrayList<>();
MyRecursiveAction subtask1 = new MyRecursiveAction(this.workload / 2);
MyRecursiveAction subtask2 = new MyRecursiveAction(this.workload / 2);
subTasks.add(subtask1);
subTasks.add(subtask2);
return subTasks;
}
public static void main(String[] args) {
MyRecursiveAction myRecursiveAction = new MyRecursiveAction(24);
ForkJoinPool forkJoinPool = new ForkJoinPool(4);
forkJoinPool.invoke(myRecursiveAction);
}
}
Check the following excerpt -
System.out.println("Doing work myself1 " + this.workload);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Done it ya " + this.workload);
I added a sleep of 1 second and then I printed another statement. However if I run the code, I don't see that statement getting printed. I don't understand why. Why will that not get printed ? In fact the result of the execution is -
Splitting workload :: 24
Doing work myself1 12
Doing work myself1 12
I was expecting the following line as well - "Done it ya"..

Make workload static and volatile:
private static volatile long workload = 0;
Loose the this.workload for just workload.
Alter if statement to:
if(workload > 0) {
Then you will get to "Done it ya".

I have found the reason as to why the last line was not getting printed.This is because fork works in asynchronous way. So its altogether a different thread which sleeps for some time. In asynchronous programming, there is no need for the main thread to wait for the response to come back unless we via code add some constructs. In this case by the time thread wakes up after 1 second, the main thread is already over.
To force the main thread to wait for execution of other threads, we need to use JOIN.
ForkJoinTask.join(): This method blocks until the result of the computation is done.
So if I add the following block
for(RecursiveAction subtask : subtasks) {
subtask.join();
}
the main thread waits and we get all the expected lines printed on the console.

Related

Producer-Consumer : Parallel Programming

my question is really simple : is this program valid as a simulation of the producer-consumer problem ?
public class ProducerConsumer {
public static void main(String[] args) {
Consumers c = new Consumers(false, null);
Producer p = new Producer(true, c);
c.p = p;
p.start();
c.start();
}
}
class Consumers extends Thread {
boolean hungry; // I want to eat
Producer p;
public Consumers(boolean hungry, Producer p) {
this.hungry = hungry;
this.p = p;
}
public void run() {
while (true) {
// While the producer want to produce, don't go
while (p.nice == true) {
// Simulation of the waiting, to check if it doesn't wait and
//`eat at the same time or any bad interleavings
System.out.println("Consumer doesn't eat");
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 3; i++) {
try {
sleep(1000);
// Because the consumer eat, the producer is boring and
// want to produce, that's the meaning of the nice.
// This line makes the producer automatically wait in the
// while loop as soon as it has finished to produce.
p.nice = true;
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Consumer eat");
}
hungry = false;
System.out.println("\nConsumer doesn't eat anymore\n");
}
}
}
class Producer extends Thread {
boolean nice;
Consumers c;
public Producer(boolean nice, Consumers c) {
this.nice = nice;
this.c = c;
}
public void run() {
while (true) {
/**
* I begin with the producer so the producer, doesn't enter the
* loop because no food has been produce and hungry is
* exceptionally false because that's how work this program,
* so at first time the producer doesn't enter the loop.
*/
while (c.hungry == true) {
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer doesn't produce");
}
/**
* While the consumer wait in the while loop of its run method
* which means that nice is true the producer produce and during
* the production the consumer become hungry, which make the
* loop "enterable" for theproducer. The advantage of this is
* that the producer already knows that it has to go away after
* producing, the consumer doesn't need to tell him
* Produce become true, and it has no effect for the first round
*/
for (int i = 0; i < 3; i++) {
try {
sleep(1000);
c.hungry = true;
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer produce");
}
/**
* After a while, producer produce, the consumer is still in the
* loop, so we can tell him he can go, but we have to make
* sure that the producer doesn't pass the loop before the
* consumer goes out and set back produce to true will lead the
* consumer to be stuck again, and that's the role of the,
* c.hungry in the for loop, because the producer knows it has
* some client, it directly enter the loop and so can't
* starve the client.
*/
System.out.println("\nProducer doesn't produce anymore\n");
nice = false;
}
}
}
I didn't use any synchronization, wait or notify, so for a parallel programming problem it seems very strange, but when I run it there aren't any deadlocks, starvation or bad interleavings, the producer produces, then stop, the consumer eats and then stops and again as many time as I wanted.
Have I cheat somewhere ?
Thanks !
P.S- I don't know why but the first line of my question doesn't appear, it was just said hello
First of all, careful with the naming, "Consumers" is misleading, you are only simulating a lone consumer. Nice can also be replaced with "producing".
Secondly, you're using while(condition) sleep, which is basically the less efficient, non protected version of a semaphore wait, so you did use a form of wait.
E.G.
while (p.nice == true) {
System.out.println("Consumer doesn't eat");
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
is your P()
System.out.println("\nProducer doesn't produce anymore\n");
nice = false;
is your V()
This method, however is both inefficient (the waiting thread is either busy waiting or sleeps for a moment while being able to go) and unprotected (because there is no protection for simultaneous access of nice and hungry, you won't be able to expand this program with more Consumers or Producers).
Hope this helps.

My app crashes when I try to send a request to the server

Well, it actually works pretty well on my android studio simulator but when I try to run it on my phone it just crashes.
I just want to send a number to the server and get a response with the data that I need to that number. so this is my code which do that:
thread = new Thread() {
#Override
public void run() {
//server stuff
try {
//Connecting
if(!userClass.equals("")) {
Log.i(debugString, "Attempting to connect to server");
socket = new Socket(hostname, portnumber);
Log.i(debugString, "Connection established!");
BufferedWriter bw = new BufferedWriter((new OutputStreamWriter(socket.getOutputStream())));
bw.write("" + userClass);
bw.newLine();
bw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
input = br.readLine();
}
} catch (IOException e) {
Log.e(debugString, e.getMessage());
} finally {
threadComplete = true;
}
}
};
thread.start();
while(!threadComplete)
continue;
then I just use this thread whenever I want to get the updated info for my request like that:
String getUserClass = userClass;
if(!getUserClass.equals(""))
{
threadComplete = false;
userClass = getUserClass;
thread.start();
while (!threadComplete)
continue;
changes.setText(input);
}
else Toast.makeText(this, "Error, choose your class", Toast.LENGTH_SHORT).show();
BTW, in the end of every thread (on the emulator because on my phone it crashes) I get a message:
Skipped 91 frames! The application may be doing too much work on its main thread.
and I have another problem, I also use IntentService to run my app service on the background, and obviously I don't want it to run constantly forever, so I made a loop which contains at the end of each loop a wait() command, but the problem is that when I set the time to wait for longer than 3000 milliseconds or so, the service crashes.
my code for the background service:
synchronized (this) {
int count = 0;
while (count<4) {
try {
wait(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (notifications && !userClass.equals("")) {
new Thread() {
#Override
public void run() {
//server stuff
try {
//Connecting
if (!userClass.equals("")) {
Log.i("debug", "Attempting to connect to server");
socket = new Socket(hostname, portnumber);
Log.i("debug", "Connection established!");
BufferedWriter bw = new BufferedWriter((new OutputStreamWriter(socket.getOutputStream())));
bw.write("" + userClass);
bw.newLine();
bw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
input = br.readLine();
}
} catch (IOException e) {
Log.e("debug", e.getMessage());
} finally {
complete = true;
}
}
}.start();
while (!complete)
continue;
Toast.makeText(this, "" + input, Toast.LENGTH_SHORT).show();
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.chanka)
.setContentTitle("ביטול שיעורים: ")
.setContentText(input);
mNotifyMgr.notify(mNotificationId, mBuilder.build());
mNotificationId++;
Toast.makeText(this, "" + input, Toast.LENGTH_SHORT).show();
count++;
}
}
}
This following piece of code is the culprit -
while (!threadComplete)
continue;
You are kind of putting the main thread on a long loop. Android does not allow that. The general construct in these kind of use cases is this -
Step 1 - Show a progress dialog to the user indicating that you are
doing something important and user needs to wait till that is
complete. Show some meaningful text in the progress dialog which makes
sense to the user.
Step 2 - Start a async connection to the server. There are lot of
options in Android to do this. But for your purpose AsyncTask might
be useful. Connect to your server, fetch and parse data in the
doInBackground method of AsyncTask and once the task is complete,
let onPostExecute publish the same to the Main thread.
Step 3 - Once you get back the result from the Async task, you may
dismiss the progress dialog and continue with whatever you were doing.
Please note that the main thread should not be blocked at any time. This is the event handling thread of the app and handles all events (User initiated or system initiated). If the thread is blocked, you get the kind of error you are seeing now. Specifically in your case, Android system is not able to do some draw operations because of the while loop.
Create a new Asynctask and run the socket establisment codes inside it :)
socket = new Socket(hostname, portnumber);

apache curator: lock revocation not working

short: I want to create a lock with one client and release it with another; so I am trying to use revocation for that end. It isn't working. more details (and my code) are below.
any help is appreciated!
long: have a system where one thread (with its own client) sets the first lock (update), then a second thread (with a client that may or may not be the same as the original client) will set a second lock; then do some work, then release that lock, and then release the first lock this code simulates two threads by having two different clients get locks.
the second client is unable to revoke the lock from the first client, however. the 'revocation listener' is never triggered. have scoured the web and not found examples.
this code assumes that you have a zookeeper server running on your local host at port 2181
ideally, I'd also like to look up from somewhere else real quick to see if the lock is in place, but perhaps an acquire with a very short timeout (5 milliseconds) would accomplish that.
also, is it a good idea to reap away locks after releasing them? (to not clog up the system?)
thanks
-Jill
ps: also posted on the apache curator user mailing list
I'll cross-post answers if I have them.
Got one answer from the mailing list: Jordan Zimmerman
8:46 PM (13 hours ago) There are a
number of problems:
The docs are not clear on this, but makeRevocable() must be called BEFORE the lock is acquired. Please submit a Jira/PR to fix the doc.
In your test, Revoker.attemptRevoke was using the incorrect path. It must be the path of the lock, so: "Revoker.attemptRevoke(client2,
ipMutex.getLockPath());”
InterProcessMutex keeps track of the thread that owns the lock. So, the lock.release(); in your revoker won’t work. I suggest using
InterProcessSemaphoreMutex instead.
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.recipes.locks.RevocationListener;
import org.apache.curator.framework.recipes.locks.Revoker;
import org.apache.curator.retry.ExponentialBackoffRetry;
public class MultipleClientExample {
/*entry point
*/
public static void main(String[] args){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
String zookeeperConnectionString = "127.0.0.1:2181";
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client.start();
try {
System.out.println("testing locks....");
InterProcessMutex ipMutex = new InterProcessMutex(client, "/mpx-updates/guid123/update");
boolean acquired = ipMutex.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(update)?" + acquired);
RevocationListener<InterProcessMutex> rl = new MyRevocationListener();
ipMutex.makeRevocable(rl);
InterProcessMutex ipMutex2 = new InterProcessMutex(client, "/mpx-updates/guid123/swap");
boolean a2 = ipMutex2.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(swap)?" + a2);
System.out.println("got the first lock in this process? " + ipMutex.isAcquiredInThisProcess());
// make a new client; see if it can get the lock!
CuratorFramework client2 = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client2.start();
InterProcessMutex ipMutex1Retry = new InterProcessMutex(client2, "/mpx-updates/guid123/update");
boolean a3 = ipMutex1Retry.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(retry/update) ?" + a3);
System.out.println("got the first lock in this process? " + ipMutex1Retry.isAcquiredInThisProcess());
Revoker.attemptRevoke(client2, "/mpx-updates/guid123/update");
a3 = ipMutex1Retry.acquire(3, TimeUnit.SECONDS);
System.out.println("AGAIN: got the lock(retry/update) ?" + a3);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class MyRevocationListener implements RevocationListener<InterProcessMutex> {
/*
* (non-Javadoc)
*
* #see org.apache.curator.framework.recipes.locks.RevocationListener#revocationRequested(java.lang.Object)
*/
#Override
public void revocationRequested(InterProcessMutex lock) {
//this seems to never be called
Collection<String> participantNodes = null;
try {
System.out.println("revocation was requested....");
System.out.println("ick ick revocation requested....");
participantNodes = lock.getParticipantNodes();
lock.release();
System.out.println("revoked lock at path: " + participantNodes);
} catch (Exception e) {
System.out.println("problem revoking lock with path: " + participantNodes + "; it was not revoked");
}
}
}
}

CyclicBarrier code not working?

I got CyclicBarrier code from oracle page to understand it more. I modified it and now having one doubt.
Below code doesn't terminate but If I uncomment Thread.sleep condition, It works fine.
import java.util.Arrays;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class Solver {
final int N;
final float[][] data;
boolean done = false;
final CyclicBarrier barrier;
class Worker implements Runnable {
int myRow;
Worker(int row) {
myRow = row;
}
public void run() {
while (!done) {
processRow(myRow);
try {
barrier.await();
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
System.out.println("Run finish for " + Thread.currentThread().getName());
}
private void processRow(int row) {
float[] rowData = data[row];
for (int i = 0; i < rowData.length; i++) {
rowData[i] = 1;
}
/*try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
done = true;
}
}
public Solver(float[][] matrix) {
data = matrix;
N = matrix.length;
barrier = new CyclicBarrier(N, new Runnable() {
public void run() {
for (int i = 0; i < data.length; i++) {
System.out.println("Data " + Arrays.toString(data[i]));
}
System.out.println("Completed:");
}
});
for (int i = 0; i < N; ++i)
new Thread(new Worker(i), "Thread "+ i).start();
}
}
public class CyclicBarrierTest {
public static void main(String[] args) {
float[][] matrix = new float[5][5];
Solver solver = new Solver(matrix);
}
}
Why Thread.sleep is required in above code?
I've not run your code but there may be a race condition, here is a scenario that reveals it:
you start the first thread, it runs during a certain amount of time sufficient for it to finish the processRow method call so it sets done to true and then waits on the barrier,
the other threads start but they see that all is "done" so they don't enter the loop and they'll never wait on the barrier, and end directly
the barrier will never be activated as only one of the N threads has reached it
deadlock
Why it is working with the sleep:
when one of the thread starts to sleep it lets the other threads work before marking the work as "done"
the other threads have enough time to work and can themselves reach the barrier
2 seconds is largely enough for 5 threads to end a processing that should not last longer than 10ms
But note that if your system is ovrerloaded it could too deadlock:
the first thread starts to sleep
the OS scheduler lets another application work during more than 2 seconds
the OS scheduler comes back to your application and the threads scheduler chooses the first thread again and lets it terminate, setting done to true
and here again the first scenario => deadlock too
And a possible solution (sorry not tested):
change your while loops for do/while loops:
do
{
processRow(myRow);
...
}
while (!done);

Stack size difference for Thread and Process

I have recently observed in Java (while implementing a deep recursive function call), that the stack size for thread is more than the process.
With this I mean, E.g. The thread could execute approx 30,000 recursive calls
while the program without thread could only go to 10,000 recursive calls to the same function.
Can any one suggest why is it so?
For better understanding and context, Please try to run the Java code as it is and see the messages printout on the console....
package com.java.concept;
/**
* This provides a mechanism to increase the call stack size, by starting the thread in the caller we can increase it
* Result were 3 times higher
*/
public class DeepRecursionCallStack {
private static int level = 0;
public static long fact(int n) {
level++;
return n < 2 ? n : n * fact(n - 1);
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(null, null, "DeepRecursionCallStack", 1000000) {
#Override
public void run() {
try {
level = 0;
System.out.println(fact(1 << 15));
} catch (StackOverflowError e) {
System.err.println("New thread : true recursion level was " + level);
System.err.println("New thread : reported recursion level was "
+ e.getStackTrace().length);
}
}
};
t.start();
t.join();
try {
level = 0;
System.out.println(fact(1 << 15));
} catch (StackOverflowError e) {
System.err.println("Main code : true recursion level was " + level);
System.err.println("Main code : reported recursion level was "
+ e.getStackTrace().length);
}
}
}

Resources