Threads, Listeners and Events
Java Threads
When a Java program starts, there is a single thread running – the main thread.
Many of the leJOS classes start extra threads running for various purposes, for example:
- Button and SensorPort start a listener thread if listeners are used
- Each Motor has a regulator thread
- The Bluetooth class starts a thread to talk to the separate Bluetooth chip
- Each Timer object starts a timer thread
User programs can create their own threads by subclassing Thread, and then
using the start method to start the thread. In leJOS NXJ 0.7, Threads can be created from any class that implements the Runnable interface.
Background threads that do not need to terminate in order for the user program to
terminate, should be marked as daemon threads by calling
setDaemon(true).
When using threads, care should be taken with concurrency issues. When data items
are accessed by multiple threads, synchronization is necessary to
ensure that data is not read when it is in an inconsistent state.
leJOS supports the standard Java synchronization mechanisms: synchronized
methods and synchronized statements using a monitor object. There are
some restrictions in the way leJOS handles concurrency and
synchronization – see the leJOS NXJ README.html file.
As an example of a leJOS thread, consider the Indicators thread in the leJOS
StartUpText menu. This is used to keep the display of the battery level
up to date, by reading its value every second, and to indicate when the
menu is uploading files or doing other communication from the PC:
import lejos.nxt.LCD;
class Indicators extends Thread {
private boolean io = false;
public void ioActive() {
io = true;
}
public void run() {
String[] ioProgress = { ". ", " . ", " . " };
int ioIndex = 0;
boolean rewrite = false;
while (true) {
try {
if (io) {
StartUpText.g.drawString(" ", 76, 0);
ioIndex = (ioIndex + 1) % ioProgress.length;
StartUpText.g.drawString(ioProgress[ioIndex], 78, 0);
io = false;
rewrite = true;
} else if (rewrite) {
LCD.drawString(" ", 13, 0);
// invert when power is off
StartUpText.g.drawString(" BT", 82, 0, !StartUpText.btPowerOn);
StartUpText.g.refresh();
rewrite = false;
}
Thread.sleep(1000);
} catch (InterruptedException ie) {
}
}
}
}
The main method starts this thread by:
Indicators ind = new Indicators();
ind.setDaemon(true);
ind.start();
Back to top
Listeners and Events
leJOS implements a listener thread that listens for particular events.
The listener thread supports:
- Button Listeners
- Sensor Port Listeners
Button listeners are used to detect when a button is pressed, whatever your program is doing at the time.
To listen for a press of a specific button, you register as listener for that button.
Example:
import lejos.nxt.*;
public class ListenForButtons {
public static void main(String[] args) throws Exception {
Button.ENTER.addButtonListener(new ButtonListener() {
public void buttonPressed(Button b) {
LCD.drawString("ENTER pressed", 0, 0);
}
public void buttonReleased(Button b) {
LCD.clear();
}
});
Button.ESCAPE.waitForPressAndRelease();
}
}
Back to top
|