So essentially I am concerned that my timertask's run method is not being called after 10 minutes because I am putting the main thread to sleep for 10 seconds to avoid crazy CPU usage to just run through an empty while loop all day. Here is the code for the java main method.
private static boolean testDone = false;
public static void main(String[] args)
{
final int minutes = 10;
final StressTest test = new StressTest(someParams);
test.start();
Timer timer = new Timer();
timer.schedule(new TimerTask(){
#Override
public void run() {
testDone = true;
int completedSynths = test.stop();
System.out.println("Completed Synths: " + completedSynths);
System.out.println("Elapsed Time in Minutes: " + minutes);
System.out.println("Throughput (synths/min): " + completedSynths/minutes);
}}, minutes*60*1000);
while(!testDone)
{
System.out.println("Still not done... sleeping for 10 secs....");
Thread.sleep(10000);
}
System.exit(0);
Even crazier, the System.out in the while loop is never printing. What have I done??
EDIT: TO add pseudocode for StressTest object
public class StressTest
{
private SecureRandom random = new SecureRandom();
private volatile int completedSynths = 0;
private volatile boolean shouldStop = false;
private Thread[] threads;
/**
* Instantiate a new StressTest object.
*
* #param threadCount number of concurrent threads to be polling server
*/
public StressTest(int threadCount)
{
threads = new Thread[threadCount];
}
public void start()
{
System.out.println("Starting Stress Test....");
for(int i = 0; i < threads.length; i++)
{
Runnable synthCaller = new SynthApiCaller();
threads[i] = new Thread(null, synthCaller, "SynthThread" + i);
threads[i].run();
}
}
public int stop()
{
System.out.println("Stopping Stress Test...");
shouldStop = true;
return completedSynths;
}
private String randId()
{
return new BigInteger(130, random).toString(32);
}
private class SynthApiCaller implements Runnable
{
#Override
public void run()
{
while(!shouldStop)
{
try
{
//this class makes an HTTP request to a server and then writes result to a file
MyClass.writeFile( "someFileLoc/file.data");
completedSynths++;
Runtime.getRuntime().exec("rm -r " + fileLoc);
System.out.println("Synth # " + completedSynths);
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
System.out.println("Thread terminated...");
}
}
}
I am concerned that my timertask's run method is not being called after 10 minutes because I am putting the main thread to sleep for 10 seconds
The Thread.sleep(...) in your main thread will not affect the running of the Timer. If the timer is not running after 10 minutes then is it possible that test.stop() is blocking?
It is important to realize that if the test is started in the main-thread and then is being stopped in the Timer thread then some synchronization will be necessary. I assume the test is running in another thread. You probably will need it to be synchronized then inside of the Timer thread you would call something like:
synchronized (test) {
test.start();
}
If you are new to Java synchronization, there are some good tutorials online.
If you are wondering whether or not the timer is being called at all, I'd set a break point inside your timer task where is sets testDone = true and see if it gets there.
Here's a good tutorial of using a debugger in eclipse.
Even crazier, the System.out in the while loop is never printing. What have I done??
As #assylias mentioned, the System.out(...) in your while loop not showing up must mean that testDone is set to true. Since testDone is being updated and accessed in different threads, you need to make sure it is also volatile.
I just ran your code sample without the test.start() and stop() and it seems to work fine. The problem may be in your test code.
Still not done... sleeping for 10 secs....
Still not done... sleeping for 10 secs....
...
Completed Synths: 1
Elapsed Time in Minutes: 10
Throughput (synths/min): 0
Now that you've added more code, here are some comments:
completedSynths++; should be changed to be an AtomicInteger. ++ is not an atomic operation so even tho the field is volatile, multiple threads can overwrite each other's increment.
If you are trying to wait for the threads to complete, instead of sleeping for 10 minutes, I'd recommend calling thread[i].join() with the threads. Even better would be use an ExecutorService and use the awaitTermination(...) method.
You call shouldStop = true; and then return the completedSynths;. You may want to wait for the threads to finish or something.
I'd not pass in a null ThreadGroup to the Thread constructor. Just use the constructor without the ThreadGroup.
I suggest making testDone volatile. As it is, I don't see anything forcing changes to testDone to be visible to reads in threads other than the one making the change.
Related
This method repeatedly reads commands and execute them until the game is over. The finished variable, when true, means that the player/user has hit Quit and wants to end the game - thus exiting the loop and executing till the end of the method.
import org.apache.commons.lang3.time.StopWatch;
private Parser parser;
private Command command;
private StopWatch stopWatch;
public void play()
{
stopWatch = new StopWatch();
stopWatch.start();
long timeLimit = 5000;
boolean finished = false;
printWelcome();
while (finished == false)
{
System.out.println(stopWatch.getTime() + " milliseconds");
if (stopWatch.getTime() >= timeLimit)
{
System.out.println("Time limit of " + timeLimit + " milli seconds has been reached. Good bye!");
return;
}
else
{
command = parser.getCommand();
finished = processCommand(command);
}
}
System.out.println("Thank you for playing. Good bye.");
}
But I'm observing a strange behaviour with the loop. It loops perfectly fine (displaying the continuous count of stopWatch.getTime() when the following lines are omitted :
else
{
command = parser.getCommand();
finished = processCommand(command);
}
But when I put them back in, it stops displaying the continuous incrementing time of the stopWatch as it increases towards the timeLimit (at which point, it should stop). Even if the player hasn't entered any command or input.
The stopWatch is clearly running in the background, but it doesn't display the count.
Please advise. Thanks.
Even if the player hasn't entered any command or input.
If Parser#getCommand is a method that is waiting for user input, execution will block until the user enters input. This means the while loop won't run and you won't see it printing out the new time.
Doing what you ask would make a very jarring experience for the user anyway, since it would mean that it would keep printing while they are typing in the command, and that's not very user-friendly.
You can use a producer-consumer approach for this. I have adapted the code from the linked question:
// Shared queue
final Queue<String> commands = new ConcurrentLinkedQueue<>();
// Non-blocking consumer
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
// non-blocking
if((String command = commands.poll()) != null) {
processCommand(command);
}
}
}, 0, 10, TimeUnit.MILLISECONDS);
// Blocking producer (this is basically the logic from Parser#getCommand)
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
commands.add(sc.next());
}
However, this solution doesn't really let you implement the timeout. So you would have to create a new class that "wraps" the Runnable so that you can cancel it after a timeout (similar to this approach):
public class TimeOutableRunnable implements Runnable {
private final Queue<String> commands;
private final Runnable wrapped;
private volatile ScheduledFuture<?> self;
public TimeOutableRunnable(Runnable wrapped, Queue<String> commands) {
this.commands = commands;
this.wrapped = wrapped;
}
#Override
public void run() {
if(commands.isEmpty()) {
self.cancel(false);
} else {
wrapped.run();
}
}
public void runWithTimeout(ScheduledExecutorService executor, long timeout, TimeUnit unit) {
self = executor.scheduleAtFixedRate(this, 0, timeout, unit);
}
}
Then you could do:
final Queue<String> commands = new ConcurrentLinkedQueue<>();
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
new TimeOutableRunnable(new Runnable() {
#Override
public void run() {
// non-blocking
while((String command = commands.poll()) != null) {
processCommand(command);
}
}
}, commands).runWithTimeout(executor, timeLimit, TimeUnit.MILLISECONDS);
I haven't tested this out and I wouldn't rate myself very high on concurrency so let me know if there is something fundamentally wrong with this approach.
I presume your parser.getCommand(); is blocking until there is input. As this while loop runs in one thread, the program is stopped at this point.
The easiest way to check if I'm right is to enter any command, and you should get some output from this line:
System.out.println(stopWatch.getTime() + " milliseconds");
You either need to implement a timeout in this method, or have a second thread counting time and interrupting the wait.
Perhaps I'm misunderstanding your question, but it sounds like your problem that it isn't printing continuously? If so, its because your parer is waiting for user input. Threading could fix this problem, run your timer and print in a seperate thread
I got an answer from my last question. But now I am unable to use and stop the Thread just after one minute after doing my things. I actually want to close/stop the thread after one minute after doing my things. So, I'm badly confused: how can I do this using:
public class Frame2 extends javax.swing.JFrame implements Runnable{
public Frame2() {
initComponents();
}
public void run(){
long startTime = System.currentTimeMillis();
while (( System.currentTimeMillis() - startTime ) < 1000) {
System.out.print("DOING MY THINGS");
}
}
}
The problem is that it is not working at all and when I close the frame containing this Thread the line of code
System.out.print("DOING MY THINGS");
works in an infinite loop.
Thanks in advance.
when I close the frame containing this Thread
Frame does not contain threads. Frame can have a reference to it. But the thread itself will run until it's execution is complete (run method ends) and not a second less.
You can not just "stop" the Thread. It must always complete it's execution (again, run method to end).
The code you wrote should be working pretty well and stop writing stuff in 60 seconds. If you want it to terminate on you closing the frame, you should add some variable to check against and write true to it when you want the thread to terminate.
Example:
private volatile boolean terminated = false;
public void run(){
long startTime = System.currentTimeMillis();
while (!terminated && System.currentTimeMillis() < startTime + 60000) {
System.out.print("DOING MY THINGS");
// here I want to do my things done in just one minute
// and after that I want to stop the thread at will!
}
}
public void stop() {
terminated = true;
}
Sorry for my bad formatting. I am using a notepad to write my programs.
This is a working code. The only question I have is, I have read that notify and wait must be used in a Synchornized block. However, in the following example, wait and notify are not used in a synchronized block and still no error is thrown.
class counthrd implements Runnable {
Thread thrd;
String x;
counthrd cnt1;
counthrd() {
}
boolean suspended;
boolean stopped;
counthrd(String s, counthrd cnt1) {
thrd = new Thread(this, s);
this.cnt1 = cnt1;
thrd.start();
x = s;
}
public void run() {
try {
System.out.println("Starting " + thrd.currentThread().getName());
for (int i = 1; i < 100; i++) {
System.out.print(i + " ");
if ((i % 10) == 0) {
System.out.println();
Thread.sleep(500);
}
//synchronized(cnt1){
while (suspended) {
System.out.println("going to wait mode");
wait();
notify();
}
//}
}
} catch (Exception e) {
System.out.println(e);
}
}
synchronized void suspendme() {
suspended = true;
notify();
}
synchronized void resumeme() {
suspended = false;
notify();
}
}
class counter {
public static void main(String args[]) throws InterruptedException {
counthrd cnt1 = new counthrd();
counthrd cnthrd1 = new counthrd("thrd 1", cnt1);
Thread.sleep(1000);
System.out.println("going to wait mode");
cnt1.suspendme();
Thread.sleep(1000);
System.out.println("resuming");
cnt1.resumeme();
Thread.sleep(1000);
}
}
See my comment. Since IllegalMonitorStateException is never thrown, we know that wait is never being called.
Notice you have two instances of counthrd...
counthrd cnt1 = new counthrd();
counthrd cnthrd1 = new counthrd("thrd 1", cnt1);
See which instance you're calling suspendme and resumeme on?
Thread.sleep(1000);
System.out.println("going to wait mode");
cnt1.suspendme();
Thread.sleep(1000);
System.out.println("resuming");
cnt1.resumeme();
Thread.sleep(1000);
cnt1 is initialized using your no-arg constructor, seen here:
counthrd() {
}
The point is that cnt1 never actually starts its own thread. It never does anything, really. cnthrd1 is the one that starts a thread, as seen here:
counthrd(String s, counthrd cnt1) {
thrd = new Thread(this, s);
this.cnt1 = cnt1;
thrd.start();
x = s;
}
The point to make is that suspended is an instance field, and not shared between cnt1 and cnthrd1. Modifying cnt1.suspended will not cause cnthrd1 to go into "wait mode". wait is never called, and thus the exception is never thrown.
To demonstrate, try calling suspendme and resumeme on cnthrd1, instead... :-)
C:\dev\scrap>javac counter.java
C:\dev\scrap>java counter
Starting thrd 1
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
going to wait mode
going to wait mode
java.lang.IllegalMonitorStateException
resuming
That being said, I figured I'd suggest you do some stuff that your code should be doing.
Declare suspended as volatile. Without some explicit memory ordering guarantees, there's no guarantee when or even if cnthrd1 reads the updated value of suspended.
Ditch the cnt1 field and instance; there's no reason for them. Get rid of that empty constructor, too.
Thread.currentThread is a static method; you don't need to use an instance for it. That all aside, thrd is guaranteed to equal Thread.currentThread here.
counthrd.x is equal to thrd.getName; why not just use x instead?
Use some better, more descriptive names. For example, instead of x, why not name? Instead of thrd, why not thread? Instead of counthrd, why not CountingThread?
You only need to call notify in resumeme, not suspendme. (in fact, calling notify in suspendme could accidentally trigger an InterruptedException if the thread is sleeping i.e. when (i % 10) == 0)
You also don't want notify in the while (suspended) loop. Your while loop can actually be turned into an if statement, too, now.
As previously stated, you need synchronized (this) around your code that calls while.
Avoid doing real logic in the constructor, e.g. thrd.start().
suspend doesn't need to be synchronized. resume doesn't need to be synchronized, either; only the wait and notify calls require it.
You can find a modified version of your example that works properly here.
I'm having a-bit of trouble with threads in java. Basically Im creating an array of threads and starting them. the point of the program is to simulate a race, total the time for each competitor ( i.e. each thread ) and pick the winner.
The competitor moves one space, waits ( i.e. thread sleeps for a random period of time between 5 and 6 seconds ) and then continues. The threads don't complete in the order that they started as expected.
Now for the problem. I can get the total time it takes for a thread to complete; what I want is to store all the times from the threads into a single array and be able to calculate the fastest time.
To do this should I place the array in the main.class file? Would I be right in assuming so because if it was placed in the Thread class it wouldn't work. Or should I create a third class?
I'm alittle confused :/
It's fine to declare it in the method where you invoke the threads, with a few notes:
each thread should know its index in the array. Perhaps you should pass this in constructor
then you have three options for filling the array
the array should be final, so that it can be used within anonymous classes
the array can be passed to each thread
the threads should notify a listener when they're done, which in turn will increment an array.
consider using Java 1.5 Executors framework for submitting Runnables, rather than working directly with threads.
EDIT: The solution below assumes you need the times only after all competitors have finished the race.
You can use a structure that looks like below, (inside your main class). Typically you want to add a lot of you own stuff; this is the main outline.
Note that concurrency is not an issue at all here because you get the value from the MyRunnable instance once its thread has finished running.
Note that using a separate thread for each competitor is probably not really necessary with a modified approach, but that would be a different issue.
public static void main(String[] args) {
MyRunnable[] runnables = new MyRunnable[NUM_THREADS];
Thread[] threads = new Thread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
runnables[i] = new MyRunnable();
threads[i] = new Thread(runnables[i]);
}
// start threads
for (Thread thread : threads) {
thread.start();
}
// wait for threads
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
// ignored
}
}
// get the times you calculated for each thread
for (int i = 0; i < NUM_THREADS; i++) {
int timeSpent = runnables[i].getTimeSpent();
// do something with the time spent
}
}
static class MyRunnable implements Runnable {
private int timeSpent;
public MyRunnable(...) {
// initialize
}
public void run() {
// whatever the thread should do
// finally set the time
timeSpent = ...;
}
public int getTimeSpent() {
return timeSpent;
}
}
I'd like to write a java while loop that will iterate for 15 seconds. One way I thought to do this would be to store the current system time + 15sec and then compare that to the current time in the while loop signature.
Is there a better way?
The design of this depends on what you want doing for 15s. The two most plausible cases are "do this every X for 15s" or "wait for X to happen or 15s whichever comes sooner", which will lead to very different code.
Just waiting
Thread.sleep(15000)
This doesn't iterate, but if you want to do nothing for 15s is much more efficient (it wastes less CPU on doing nothing).
Repeat some code for 15s
If you really want to loop for 15s then your solution is fine, as long as your code doesn't take too long. Something like:
long t= System.currentTimeMillis();
long end = t+15000;
while(System.currentTimeMillis() < end) {
// do something
// pause to avoid churning
Thread.sleep( xxx );
}
Wait for 15s or some other condition
If you want your code to be interrupted after exactly 15s whatever it is doing you'll need a multi-threaded solution. Look at java.util.concurrent for lots of useful objects. Most methods which lock (like wait() ) have a timeout argument. A semaphore might do exactly what you need.
As already mentioned by other posters, if you just want the thread to pause for some time use Thread.sleep().
If you want the thread to do something, but want to make it stop after a while, use something like:
class Foo implements Runnable {
private volatile boolean killed = false;
public void run() {
while (!killed) {
try { doOnce(); } catch (InterruptedException ex) { killed = true; }
}
}
public void kill() { killed = true; }
private void doOnce() throws InterruptedException { /* .. */ }
}
and from the main thread, do:
Foo foo = new Foo();
Thread thread = new Thread(foo);
thread.start();
/* when you want to stop it */
foo.kill();
thread.interrupt();
Your general approach seems fine although you may want to see if the current time is greater than the point you want to stop, otherwise, you might be running for a long time.
The alternative is to run a timer/thread that sets a flag after 15 seconds have elapsed. This flag would have to be marked as volatile otherwise your loop might not see the change occur in the value.
The choice if you care about efficiency is which is more expensive, getting the system time once per loop or accessing a volatile variable? I don't know which one is more efficient - you could benchmark it if it's really important.
For simple, maintainable code, I'd choose the timer check approach:
long endTime = System.currentTimeMillis() + 15000
while (System.currentTimeMillis() < endTime) {
//loop
}
try this:
public class SleepMessages {
public static void main(String args[]) throws InterruptedException {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
for (int i = 0; i < importantInfo.length; i++) {
//Pause for 15 seconds
Thread.sleep(15000);
//Print a message
System.out.println(importantInfo[i]);
}
}
}
more info : here
Never check for current time in a tight loop.
Otherwise somebody with a laptop can get get his/her lap burned by an overheated CPU. I heard the stories of this actually happening.
You can use AOP and a #Timeable annotation from jcabi-aspects (I'm a developer):
#Timeable(limit = 1, unit = TimeUnit.SECONDS)
String load(String resource) {
// do this check regularly:
if (Thread.currentThread.isInterrupted()) {
throw new IllegalStateException("time out");
}
// execution as normal
}
When time limit is reached your thread will get interrupted() flag set to true and it's your job to handle this situation correctly and to stop execution.
Assuming you want the loop to do something sensible, you might find it faster to check a volatile flag. Have another thread wait 15 seconds (or use a timer) and then set it.
Alternatively, if you know roughly how long the loop body will take, run it a few hundred times, say, and do the time check in an outer loop.
final long start = System.nanoTime();
do {
for (int i=0; i<200, ++i) {
...
}
} while (System.nanoTime()-start < 15L*1000L*1000L*1000L);
System.nanoTime should not get confused by system clock changes. Use of long literal numbers is important.
You might be interested in scheduling a TimerTask that stops another thread or changes the condition of your loop.
For the java.util.concurrent approach, refer to Chapter 6 of Java Concurrency in Practice (section 6.3.7 Placing time limits on tasks, page 131).
Code example: Fetching an advertisement with a time budget.
A solution similar to #Tom Hawtin without an arbitary loop size.
final long end = System.nanoTime() + 15 * 1000 * 1000 * 1000L;
int loop = 1;
do {
for (int i=0; i<loop; ++i) {
...
}
loop++;
} while (System.nanoTime() < end);
In this case the size of the inner loop will start small but grow in size if the loop is particularly quick. If it is slow enough, it might only iterate once.
Here is my suggestion and it's working good for me :)
StoppingTime = 15 ;
int loop = 1;
long StartTime = System.currentTimeMillis() / 1000 ;
for (int i=0; i<loop; ++i) {
// your code here
loop++;
if (((System.currentTimeMillis()/1000) - StartTime) > StoppingTime)
loop=0;
}
I would suggest you do this with the timer class avoiding the Thread.sleep(xxx); method.
for example:
import java.util.Timer;
import java.util.TimerTask;
public class TimerExample {
private int globalTimer = 0;
private int limitTimer = 15;
public static void main(String[] args) {
new TimerExample();
}
public TimerExample() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
globalTimer++;
// DO YOUR CODE HERE
System.out.println("running");
if (globalTimer == limitTimer) {
timer.cancel();
}
}
}, 0, 1000);
}
}
Use an object array as your local variable to pass to the thread. In your loop check to see if that variable has been changed by your thread.
NB
Its important to use an Array Of Object since a thread's run method will be able to access it even if it was a local variable.
How?
Create a new Thread
In the run method sleep(1000*15) for 15 seconds
Update your local variable.
//The thread method
public static boolean[] delay(int seconds) {
final boolean[] cont = new boolean[1];
cont[0] = true;
Thread thread = new Thread() {
#Override
public void run() {
try {
sleep(1000 * seconds);
cont[0] = false;
} catch (InterruptedException ex) {
}
}
};
thread.start();
return cont;
}
//The loop method
public void dance(){
//here we call our delay method time it for 15 seconds.
final boolean[] delay = delay(15);
for (int i = 0; i < size; i++) {
//your code here.
if (delay[0] == false) { //check if delay has been changed to false and break.
break;
}
}
}