PDA

View Full Version : Java Threads


Aaron V
02-22-2011, 07:35 PM
So I have experience in programming - but one thing I haven't really looked into in detail are threads - I've always just let the compiler deal with them for me. I understand the concept of threads. The different parts of a programmer running essentially at the same time (alternating fast enough so that it doesn't really make a difference). I just don't understand what parts of a program constitutes as a difference thread. I've written a few additional classes for organisational purposes - do they have any effect?

Basically my main problem is that I need to pulse solenoids. It's simple to set it open or closed based on other input, but I don't know how to use time as an input. I figure I need threads because I don't want to stop everything else in the code.

Finally I've both seen the wait() function in the object class and the delay() function in the Timer class - I'm not sure which is better to use and which thread it effects.

davidthefat
02-22-2011, 07:38 PM
There is only one thread unless you explicitly make another thread. So to answer your question: most likely the same thread as the main thread. Unless the WPILib makes threads (I think the pid calculations do it)

wdell
02-22-2011, 08:46 PM
Basically my main problem is that I need to pulse solenoids. It's simple to set it open or closed based on other input, but I don't know how to use time as an input. I figure I need threads because I don't want to stop everything else in the code.

Finally I've both seen the wait() function in the object class and the delay() function in the Timer class - I'm not sure which is better to use and which thread it effects.

How often are you trying to pulse the solenoids?


package edu.wpi.first.wpilibj.templates;

import edu.wpi.first.wpilibj.Solenoid;

public class Pulser implements Runnable {

Solenoid firstSolenoid = new Solenoid(1);

public void run() {
while (true) {
try {
firstSolenoid.set(true);
Thread.sleep(1000); // sleep thread for 1 second
firstSolenoid.set(false);
Thread.sleep(1000); // sleep thread for another second
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}


That will pulse the solenoid on for a second, then off for a second. The sleep() function causes the thread to wait (time in milliseconds).

wait() causes the thread to sleep until another thread issues a notify() or notifyAll() command. It doesn't set a specific time to wait for.

You might try replacing the sleep() function with Timer.delay(), I think that would get rid of the try..catch statements.


package edu.wpi.first.wpilibj.templates;

import edu.wpi.first.wpilibj.Solenoid;
import edu.wpi.first.wpilibj.Timer;

public class Pulser implements Runnable {

Solenoid firstSolenoid = new Solenoid(1);

public void run() {
while (true) {
firstSolenoid.set(true);
Timer.delay(1);
firstSolenoid.set(false);
Timer.delay(1);

}
}
}


To start the thread, you need to tell it to start() somewhere in your main program:


Pulser pulser = new Pulser();
new Thread(pulser).start();

Robby Unruh
02-22-2011, 08:47 PM
So I have experience in programming - but one thing I haven't really looked into in detail are threads - I've always just let the compiler deal with them for me. I understand the concept of threads. The different parts of a programmer running essentially at the same time (alternating fast enough so that it doesn't really make a difference). I just don't understand what parts of a program constitutes as a difference thread. I've written a few additional classes for organisational purposes - do they have any effect?

Basically my main problem is that I need to pulse solenoids. It's simple to set it open or closed based on other input, but I don't know how to use time as an input. I figure I need threads because I don't want to stop everything else in the code.

Finally I've both seen the wait() function in the object class and the delay() function in the Timer class - I'm not sure which is better to use and which thread it effects.

Pulse solenoids, eh? Take a closer look at the Timer (http://www.wbrobotics.com/javadoc/edu/wpi/first/wpilibj/Timer.html) class, more notably getFPGATimestamp(). What I'd do is create a double to store a current timestamp using getFPGATimestamp(). Then in my code I'd make another more recent one that checks for a change in time. If the time has changed, I'd simply set the solenoid to false. Put that baby in a loop and bam! :D

Now if you'd prefer putting it in a thread than a loop, just make a Runnable interface and thread it.

Hope I helped.

Aaron V
02-22-2011, 09:22 PM
Alright, thanks everyone - I think I understand.

By default there is only one main thread. If I want to create a thread I can use the Thread class and can pass it a class inherited from "Runnable." Then no pauses in the run function will distract the main code.

To pause the thread I can either use the Timer class or the wait function, but the wait function requires a try...catch function.

Thanks for the quick responses.

dale5alfred
03-13-2011, 04:46 AM
What are three ways in which a thread can enter the waiting state?

Chris27
03-13-2011, 03:00 PM
Alright, thanks everyone - I think I understand.

By default there is only one main thread. If I want to create a thread I can use the Thread class and can pass it a class inherited from "Runnable." Then no pauses in the run function will distract the main code.

To pause the thread I can either use the Timer class or the wait function, but the wait function requires a try...catch function.

Thanks for the quick responses.

fyi, Runnable is an interface not a class.

Ether
03-13-2011, 05:06 PM
You might try replacing the sleep() function with Timer.delay(), I think that would get rid of the try..catch statements.

Sleep() makes the thread not runnable so it releases the processor so it doesn't waste resources polling the clock. The sleeping thread becomes runnable again when the sleep period has expired.


How is Timer.delay() implemented?

colinwarren
03-13-2011, 07:17 PM
Sleep() makes the thread not runnable so it releases the processor so it doesn't waste resources polling the clock. The sleeping thread becomes runnable again when the sleep period has expired.


How is Timer.delay() implemented?





public static void delay(final double seconds) {
try {
Thread.sleep((long) (seconds * 1e3));
} catch (final InterruptedException e) {
}
}


From WPILibJ's source. I would expect that the C++ threads are implemented on top of usleep(3) (http://developer.apple.com/library/mac/#documentation/darwin/reference/manpages/man3/usleep.3.html).

purduephotog
03-13-2011, 10:26 PM
We ran a neat little experiment (at least to me) to understand how the underlying threads were being executed.

Set the motor speed to one value- and then immediately set it to another value.

What we ended up with is a 'pulse' - sometimes it would hold continuous values... othertimes it would slow/speed up.

I had hoped it would help drive some points in with the programmers.

Ether
03-13-2011, 10:43 PM
We ran a neat little experiment (at least to me) to understand how the underlying threads were being executed.

Set the motor speed to one value- and then immediately set it to another value.

What we ended up with is a 'pulse' - sometimes it would hold continuous values... othertimes it would slow/speed up.

I had hoped it would help drive some points in with the programmers.

How did this help you understand how threads are being executed? What points were you hoping to drive home?

purduephotog
03-14-2011, 11:54 AM
How did this help you understand how threads are being executed? What points were you hoping to drive home?




Calls were being done asynchronously. That meant they were not executing in a linear fashion and you could not guarantee which would execute first.

If they executed linearly and in order, you'd have either no pulse (since the first set would be overridden when the code exited the loop) or a constant pulse rate since both calls were made in sequence, one after another, with no delays other than what the scheduler created.

Which mean the scheduler was pausing the robot.main classes and running things in the background- interrupt, so to speak, the main thread transparently. The students didn't (and still don't, I think) understand the implications of this. They think it just runs and runs and runs... they never see the pauses because they aren't presented to them.

One of the biggest issues I've had in trying to teach (and even some adults) is that just because you put two lines next to each other in the code- when dealing with hardware- you never know for certain (unless you're VERY careful) that they will execute properly. So it is always best to design with that thought in mind....

Ether
03-22-2011, 07:57 PM
To start the thread, you need to tell it to start() somewhere in your main program

If you start several threads at the same priority, what scheduling policy is used to run them concurrently?

Someone said it was not time-based, but rather based on number of bytecodes executed. Is this correct, and can anyone link to a document where this is discussed? I'm referring to the 2011 FRC Java Framework implementation here specifically.