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.
Related
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.
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?
The following snippet is a thread named "Foo" that sleeps for 1 minute and then copies the data typed in 1 minute to a log file.
while(isStarted) {
try {
Thread.sleep(60000); // sleep for 1 minute
ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
int result = copy.copyToLogFile(keyStrokeList);
System.out.println(result);
} catch(Exception exc) {
exc.printStackTrace();
}
}
I will describe one situation :
Foo thread has finished copying all the data typed in last one minute and it has been 30 seconds since it is asleep. This thread unaware of the situation that several keys are being tapped when it is asleep,will never be able to copy the key strokes into the log file when one presses System.exit(0).
Is there any way I can interrupt this thread i.e awake it and ask it to copy the data to the log file.
Please discuss how should I approach this problem.
The situation in the question :
loop started
thread is sleeping and will sleep for 1 minute
after a minute,it gets the keys tapped in the last 1 minute and copies all that
to a file
Thread sleeps again..and will sleep for 1 minute before it copies the keystrokes
It has been about 30 seconds and thread will sleep for 30 seconds more before it starts
copying the key strokes
suddenly the user presses exit button in the application
The user wants that key strokes be recorded till the second he presses exit
I cannot do System.exit(0) before checking the thread is asleep or not
How do I do this. Should I awake it or make a different call to the list and get the
key strokes because they are being recorded ? And how shall I awake it ?
You're part way there...
while(isStarted) {
try {
Thread.sleep(60000); // sleep for 1 minute
} catch(InterruptedException exc) {
exc.printStackTrace();
}
ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
int result = copy.copyToLogFile(keyStrokeList);
System.out.println(result);
}
What you need to is provide a way to terminate the loop...
public void dispose() {
isStarted = false;
interrupt();
try {
join();
} catch(InterruptedException exc) {
exc.printStackTrace();
}
}
You should also know that the JVM will not exit until all non-daemon threads have completed (under normal shutdown). This means you can call System.exit(0) and the JVM will not terminate until the logger thread has terminated.
You could use this, but attaching a shut down hook which would have the capacity to call the dispose method on the logger thread...just a thought
You should use a shared object between 2 thread to implement wait/notify pattern instead of Thread.sleep(..) method.
In your condition, there are 2 threads:
Which reads buffer at 1 min interval. (Thread1)
Which will receive "exit" event first. (Thread2)
So, whenever you create instance of Thread1 you can pass a Java Object (new Object()) to it. Reader thread can be put into sleep using object.wait(60*1000); So it will sleep for max 1 minute if object.notify() is not called in 1 minute. If object.notify() is called in this duration, thread will immediately resume.
So, whenever user wants to exit from application you can call object.notify(); which will resume reader thread.
If I failed to explain you the solution due to my bad English please let me know. I will provide you a code sample.
Here's a fairly simple test case to show a way to do this:
public class InterruptTest
{
#Test
public void test() throws InterruptedException
{
//Create the logging thread and start it
LogRunnable runnable = new LogRunnable();
Thread t = new Thread(runnable);
t.start();
//Wait some time
Thread.sleep(3500);
System.out.println("User has pressed exit, starting shutdown");
//Tell the runnable to shut down
runnable.halt();
//Interrupt the thread to wake it up
t.interrupt();
//Wait until thread terminates
t.join();
System.out.println("Exiting");
}
private static class LogRunnable implements Runnable
{
private static final int SLEEPMS = 2000;
private boolean isStarted = true;
private int runCount = 1;
public void halt()
{
this.isStarted = false;
}
public void run()
{
while(isStarted)
{
try
{
Thread.sleep(SLEEPMS);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
catch(Exception exc)
{
exc.printStackTrace();
}
//Do work
System.out.println("Work done " + runCount++);
}
}
}
}
Output:
Work done 1
User has pressed exit, starting shutdown
Interrupted
Work done 2
Exiting
When the user presses the exit key, you signal your main thread to start shutting everything down (in the test-case, it simply waits for some time)
The logging thread is told to halt and awakened via a interrupt() -call
Before exiting, the main thread calls join() to wait until the logging thread has completed, you could consider using an overload that takes a timeout in case something goes wrong
The logging thread wakes up with InterruptedException, completes the code after the catches and terminates
After the logging thread has terminated, the main-thread returns from the join()-call and terminates
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.
I have a scenario where i want a thread to sleep for specific amount of time.
Code:
public void run(){
try{
//do something
Thread.sleep(3000);
//do something after waking up
}catch(InterruptedException e){
// interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds?
}
}
Now how do i handle the case where the thread i am trying to run is hit with an interrupted exception before the complete of the sleep? Also does the thread wake up after being interrupted and does it go to runnable state or when is it that only after it goes to runnable does the flow go to catch block?
When your thread is hit by an interrupt it will go into the InterruptedException catch block. You can then check how much time the thread has spent sleeping and work out how much more time there is to sleep. Finally, instead of swallowing the exception, it is good practice to restore the interruption status so that code higher up the call stack can deal with it.
public void run(){
//do something
//sleep for 3000ms (approx)
long timeToSleep = 3000;
long start, end, slept;
boolean interrupted;
while(timeToSleep > 0){
start=System.currentTimeMillis();
try{
Thread.sleep(timeToSleep);
break;
}
catch(InterruptedException e){
//work out how much more time to sleep for
end=System.currentTimeMillis();
slept=end-start;
timeToSleep-=slept;
interrupted=true
}
}
if(interrupted){
//restore interruption before exit
Thread.currentThread().interrupt();
}
}
According to this page you'll have to code it to behave the way you want. Using the thread above your sleep will be interrupted and your thread will exit. Ideally, you'd re-throw the exception so that whatever started the thread could take appropriate action.
If you don't want this to happen, you could put the whole thing in a while(true) loop. Now when the interrupt happens the sleep is interrupted, you eat the exception, and loop up to start a new sleep.
If you want to complete the 3 seconds of sleep, you can approximate it by having, say, 10 sleeps of 300 milliseconds, and keeping the loop counter outside a while loop. When you see the interrupt, eat it, set a "I must die" flag, and continue looping until you have slept enough. Then you interrupt the thread in a controlled manner.
Here's one way:
public class ThreadThing implements Runnable {
public void run() {
boolean sawException = false;
for (int i = 0; i < 10; i++) {
try {
//do something
Thread.sleep(300);
//do something after waking up
} catch (InterruptedException e) {
// We lose some up to 300 ms of sleep each time this
// happens... This can be tuned by making more iterations
// of lesser duration. Or adding 150 ms back to a 'sleep
// pool' etc. There are many ways to approximate 3 seconds.
sawException = true;
}
}
if (sawException) Thread.currentThread().interrupt();
}
}
using Sleep in my experience is usually to compensate for bad timing somewhere else in the program, reconsider!
try this:
public void run(){
try{
//do something
long before = System.currentTimeMillis();
Thread.sleep(3000);
//do something after waking up
}catch(InterruptedException e){
long diff = System.currentTimeMillis()-before;
//this is approximation! exception handlers take time too....
if(diff < 3000)
//do something else, maybe go back to sleep.
// interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds?
}
}
if you do not interrupt the sleep yourself, why would this thread be awoken ? is seems that you are doing something very wrong...
I use it this way:
So it is not necessary to wait the specific time to end.
public void run(){
try {
//do something
try{Thread.sleep(3000);}catch(Exception e){}
//do something
}catch(Exception e){}
}
Why do you want to sleep for exactly 3 seconds? If it's just having to execute something after some time, try using a Timer.