I'm trying to write a program to solve 2 puzzles who can't be solved independently from eachother, but have the same solution. My idea is that they both run in a seperate thread until they stop finding new pieces of information. Then they communicate what they have found by updating some shared state variables and continue if something was written by either one of them to the shared state.
I think a CyclicBarrier is the appropriate mechanism to use here. This is my code (which is running concurrently in 2 threads:
while (true) {
doSolvingLogicHere();
shareUpdates(); // this method updates the shared state variable and is synhronized
int count;
int updates = 0;
try {
count = writeBarrier.await();
updates = threadsUpdatedSomething;
if (count == 0) {
writeBarrier.reset();
threadsUpdatedSomething = 0; //'reset' the shared value
}
} catch (InterruptedException ex) {
Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
} catch (BrokenBarrierException ex) {
Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
}
if (updates == 0) { //no thread updated something
break;
} else { // at least one of the threads updated something, solving should continue in both threads
readUpdates();
}
}
ThreadsUpdatedSomething is a shared integer which is incremented in the 'ShareUpdates()' if anything at all was updated by the threads. When both threads didn't find anything new in the iteration, this means that they never will find anything new and the whole loop should be stopped for both threads. That's why I'm checking for it to be zero.
I would expect them to both stop when both threads did not write any new information in the shared state variables. But when running the program, one of the threads stop, while the other one keeps going. When debugging the program and setting breakpoints at 'readUpdates()' line, the program works as expected.
Is this the correct way for handling such a concurrent 'solving' loop? And in case it is correct, where is the error in my code?
Thanks for the help!
EDIT: Small mistake corrected. 'updates = threadsUpdatedSomething;' now at the correct place
As per API , await returns
the arrival index of the current thread, where index getParties() - 1 indicates the first to arrive and zero indicates the last to arrive
count = writeBarrier.await();
Being said , So only one of the Thread would receive the 0 . And only one thread would set the updates value to 0. Thats why the last arrived thread stopped and other one not stopped.
As per your statements , you need to stop the threads when you find both threads not updated the threadsUpdatedSomething. i assumed that time threadsUpdatedSomething would be zero.
If not you have to change the logic , some how to find when the condition has to be break and apply it
while (true) {
doSolvingLogicHere();
shareUpdates(); // this method updates the shared state variable and is synhronized
int count;
int updates = 0;
try {
writeBarrier.await();
if (threadsUpdatedSomething == 0) {
updates = threadsUpdatedSomething;
writeBarrier.reset();
threadsUpdatedSomething -= 2; //'reset' the counter by decrementing 2
}
} catch (InterruptedException ex) {
Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
} catch (BrokenBarrierException ex) {
Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
}
if (updates == 0) { //no thread updated something
break;
} else { // at least one of the threads updated something, solving should continue in both threads
readUpdates();
}
}
Also Don't forgot to set the break conditions in exception cases if required.
Related
In Java/Android, is there a way to check whether the currently executing line of code is executing on a background thread or not?
I have a lil' program I'm conjuring up that has finally reached the full-spaghetti stage... this was intentional, you see, because this way... if a competitor gets their hands on the code, and they "open the hood," after looking at it for more than 20 seconds, their hair will catch on fire and they'll run away screaming... but now even I am getting confused and I need to check for this condition somehow.
Exhibit-A:
// can be called from 1,067 places... some of which are background threads.
public void startDoingAFunDance(String caller, int wobbleIntensity, int spineAngle, int feetSeparationInInches) {
if (!validCallersForFunDance.contains(caller)) {
Log.i("XXX", "Caller not allowed.");
return;
}
boolean wasCalledFromBackgroundThread = // ? < what to put here > ?
Log.i("XXX", "Was startDoingAFunDance() called from a background thread? And the answer is: " + wasCalledFromBackgroundThread);
// classified
}
An easy way to know it might be the following
boolean wasCalledFromBackgroundThread = (Thread.currentThread().getId() != 1);
background threads doesn't have id 1 (UI thread has).
I have a producer that produces products and a consumer that consumes them. What I want is, if a product is not consumed in 5 minutes I want it to be destroyed.
This is the part of the producer:
boolean full = false;
public void produce(int p) throws RemoteException {
//choses a or b randomly
//if a or b spot is occupied, thread must wait()
synchronized(this){
if ((int)((Math.random()*10)%2) == 1){
while (a!=-1){try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(CHServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
a = p;
if (b!=-1) full = true;
notifyAll();
}
else {
while (b!=-1){try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(CHServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
b = p;
if (a!=-1) full = true;
notifyAll();
}
}
}
a & b are supposed to be my products.
I really don't know how can I measure that time for example when the thread is waiting or a client isn't trying to consume that product. This piece of code , is running on a RMI java server.
I'd just using a scheme like this: when you produce something use java.util.Timer() to set a timer for 5 minutes in the future. When the item is consumed, .cancel() the timer. If the timer goes off, do whatever cleanup you need to do.
It looks like you are implementing a queue with 2 slots, the 2 slots being a and b. But the strategy of chosing a random slot isn't optimal. You might wait for a slot while the other is empty. Also, the consumer cannot tell which one of a or b you produced first.
Anyway, if I understand the code well, you could
save the current time at the time you enter the loop.
every time you wake up from wait(), compute the delay since the entry. If it exceeds your time limit, return or throw an exception. Else, check if the slot is available.
to make sure not to wait forever, you should specify a delay on your wait. You could either wait a fixed time, maybe 1 second, or compute the wait time remaining until the 5-minute deadline.
I have a program that runs simultaneously and I have this problem where I want to stop the thread but the for loop/while loop doesn't get cancelled once I once I click enter
If I take the for loop out of the while loop, the program actually responds to the enter and shuts down.
class MyNumber extends Thread {
private volatile boolean processing = true;
public void run() {
while (processing) {
// Once I take this for loop out(put // beside it like right now), the enter key to stop the program then does work.
//for(int i = 1; i<27; i++){
System.out.println("Letter " + "i");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// }
}
}
public void permSleep() {
processing = false;
}
}
public class LetterNumber {
public static void main(String[] args) {
MyNumber num1 = new MyNumber();
num1.start();
System.out.println("Hit enter to stop the Numbers!");
Scanner shutter1 = new Scanner(System.in);
shutter1.nextLine();
num1.permSleep();
}
}
Why does the for loop cause the program to not shutdown?
I'm not really clear on what you're asking. However, if you're expecting that the while and for loops will both terminate as soon as processing is set to true, that isn't what happens. A while will execute the statement in the body (i.e. the for loop), then it will test the condition (processing == true), then if it's true, it executes the statement again, and then tests the condition again. It doesn't test it while the for loop is executing. It doesn't "notice" when the processing variable is set. So when processing is set to true, the for loop will keep going until it's done, which could be another 26 seconds.
To fix this simply, add
if (!processing)
break;
inside the for loop. Now the processing flag will be tested each time through the for loop. (If it were me, I'd put a "label" on the while loop and use that to break out of both loops.) Another way to fix it:
for(int i = 1; i<27 && processing; i++){
which means the for loop will continue only as long as processing is true.
Note: These solutions will still not test processing while the sleep(1000) is going on. So the program could still pause up to 1 second before it terminates. If you really want a solution that will terminate the sleep, you'll have use interrupt or some other concurrency feature.
It should work. Your for loop takes about 27 seconds to finish. It should come out of that after the for loop has finished.
I need to check how many events are detected within 2 seconds. I have the timer working and I have everything else working...but I ran into a problem: the loop only checks one time, per second and I can't seem to figure out how to fix that. I need it to check constantly during these two seconds to see how many events there were in total!
Here is what I have:
int seconds = 0;
System.out.println("Seconds: " + seconds);
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {}
seconds++;
System.out.println("Seconds: " + seconds);
//This needs to be looping the whole time.
//But right now, it's being blocked and only checked once
if(eventDetected() && seconds <= 2){
events++;
}
}
So you can see my problem. I can't split them up because then the second timer would run, and THEN eventDetected() would be checked. I need it to check constantly DURING the two second timer...so I basically need both things to happen at once. Is there any way I can do this?
Thanks for any help ahead of time!
I think your design pattern needs work -- I don't know what type event you're looking to detect, but no matter how short your sleep time is, there's a chance you could miss an event using the current pattern. Here's what I suggest:
Have eventDetected() increment your events counter. That way, you won't miss an event.
Then, you just need a way to turn on and off listening (and perhaps resetting the event counter). If you're sure that in you're current pattern you are really in a different thread that won't block your eventDetected() method, you could set a flag to check. For example:
When you want to start listening:
listenForEvents = true;
In eventDetected():
if (listenForEvents) { events++; }
When you want to stop listening (for example, after your Thread.sleep() call):
listenForEvents = false;
With multithreading, make sure to watch out for concurrency issues checking and setting the variables, of course.
I would tell you what kind of event I have to keep track of but then I'd have to kill you :D
Answered my own question. Hopefully this will help anyone else out who has a similar problem at some point! I looked up multithreading a bit...
I created a new class EventTimer which implements Runnable, with a public field for seconds:
public class EventTimer implements Runnable{
int seconds;
static int timerThreadCount = 0;
Thread t;
public EventTimer() {
timerThreadCount++;
this.seconds = 0;
t = new Thread(this, "Event Timer");
t.start(); // Start the thread
}
#Override
public void run() {
// TODO Auto-generated method stub
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {
System.out.println("Waiting interupted.");
}
seconds++;
System.out.println("Seconds: " + seconds);
}
}
}
Then I used an instance of the EventTimer, and used a while loop & if statement to solve my problem.
EventTimer t = new EventTimer();
while(t.seconds < 2){
if(eventDetected()) events++;
}
It was actually quite simple! I realize that each iteration of my loop of operation (since the entire code piece above is inside an infinite loop) will create a new EventTimer thread and I will eventually run into memory problems however. How would I close/end a thread after the timer has reached 2 seconds?
How do I delay a while loop to 1 second intervals without slowing down the entire code / computer it's running on to the one second delay (just the one little loop).
Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
It seems your loop runs on Main thread and if you do sleep on that thread it will pause the app (since there is only one thread which has been paused), to overcome this you can put this code in new Thread that runs parallely
try{
Thread.sleep(1000);
}catch(InterruptedException ex){
//do stuff
}
My simple ways to delay a loop.
I already put the codes here after failing to follow the stackoverflow's standards.
//1st way: Thread.sleep : Less efficient compared to 2nd
try {
while (true) {//Or any Loops
//Do Something
Thread.sleep(sleeptime);//Sample: Thread.sleep(1000); 1 second sleep
}
} catch (InterruptedException ex) {
//SomeFishCatching
}
//================================== Thread.sleep
//2nd way: Object lock waiting = Most efficient due to Object level Sync.
Object obj = new Object();
try {
synchronized (obj) {
while (true) {//Or any Loops
//Do Something
obj.wait(sleeptime);//Sample obj.wait(1000); 1 second sleep
}
}
} catch (InterruptedException ex) {
//SomeFishCatching
}
//=============================== Object lock waiting
//3rd way: Loop waiting = less efficient but most accurate than the two.
long expectedtime = System.currentTimeMillis();
while (true) {//Or any Loops
while(System.currentTimeMillis() < expectedtime){
//Empty Loop
}
expectedtime += sleeptime;//Sample expectedtime += 1000; 1 second sleep
//Do Something
}
//===================================== Loop waiting
As Jigar has indicated you can use another Thread to do work which can operate, sleep etc independently of other Threads. The java.util.Timer class might help you as well since it can perform periodic tasks for you without you having to get into multithreaded programming.