Using the Sun Java Real-Time System
- The <tt>RealtimeThread</tt> Class
- The Real-Time Garbage Collector (RTGC)
- Conclusion
The Sun Java Real-Time System (Java RTS) is a Java virtual machine implementation that is compliant with the Real-Time Specification for Java (RTSJ). Real-time Java applications are subject to some form of time constraint. For instance, if your application must perform processing at precise time intervals, or must respond to an event within a well-defined timeframe (a deadline), then you have a real-time requirement.
Building real-time applications is challenging because you must guarantee that your code meets its deadline predictably and deterministically. Java SE generally cannot meet this guarantee due to the nondeterministic behavior of the garbage collector and just-in-time (JIT) compiler, and the lack of strict priority-based dispatching of threads. Java RTS and the RTSJ solve these challenges by defining how Java applications must behave in the real-time space. Java RTS provides the runtime, APIs, and tools necessary to reason about and control the temporal behavior of your Java applications.
Based on the Java SE 5 codebase, Java RTS runs on Solaris 10, Red Hat MRG Linux, and Novell's SUSE Linux Enterprise Real-Time Extension (Red Hat and SUSE are POSIX real-time Linux products). Although these OS distributions are officially supported, you can get Java RTS to run on the latest Linux kernel with the RT-PREEMPT patches installed (a requirement to achieve real-time behavior on Linux). Let's examine some of the features of Java RTS for real-time Java development.
The RealtimeThread Class
For your code to run with real-time, deterministic characteristics in Java RTS, you must execute it within a real-time thread. To do so, create a class that extends the Runnable interface and create a javax.realtime.RealtimeThread (RTT) object in place of a java.lang.Thread to execute your application code (see Listing 1).
Listing 1: Executing a Runnable in a RealtimeThread.
import javax.realtime.*; public class MyApp { class MyRunnable implements Runnable { public MyRunnable() { // ... } public void run() { // Application logic here... } } public MyApp() { // Run at realtime priority PriorityParameters sched = new PriorityParameters( PriorityScheduler.instance().getMinPriority()); // Create the RealtimeThread to execute the runnable RealtimeThread rtt = new RealtimeThread( sched, // priority null, // release parameters null, // memory parameters null, // memory area null, // processing group new MyRunnable() ); // The runnable rtt.start(); } public static void main(String[] args) { MyApp main = new MyApp(); } }
Alternatively, your class can extend RealtimeThread directly (see Listing 2). Set your RTT's priority and other (optional) real-time characteristics, and start it like you would any Thread. You can optionally set the priority and start the RTT in the MyRealtimeClass constructor, hiding the details of the real-time implementation from the caller.
Listing 2: Extending RealtimeThread.
import javax.realtime.*; public class MyApp { class MyRealtimeClass extends RealtimeThread { public MyRealtimeClass() { // ... } public void run() { // Application logic here... } } public MyApp() { // Run at realtime priority PriorityParameters priority = new PriorityParameters( PriorityScheduler.instance().getMinPriority()); MyRealtimeClass rtt = new MyRealtimeClass(); rtt.setSchedulingParameters( priority ); rtt.start(); } public static void main(String[] args) { MyApp main = new MyApp(); } }
Depending on your requirements, you may need to perform processing on regular time intervals. Java RTS supports periodic real-time threads; through its high-resolution timer facility, it ensures that your code RTT is released at precise points in time to meet its periodic requirement. To invoke this behavior, you create a PeriodicParameters object, set the time period, and set it as your RTT's release parameter (see Listing 3). The code shown in bold illustrates the changes from the previous example.
Listing 3: Defining a periodic RealtimeThread.
// ... // Run at realtime priority PriorityParameters priority = new PriorityParameters( PriorityScheduler.instance().getMinPriority()); // 10 millisecond periodic release RelativeTime tenMillis = new RelativeTime( 10, // millisecods 0); // nanoseconds ReleaseParameters period = new PeriodicParameters( tenMillis ); MyRealtimeClass rtt = new MyRealtimeClass(); rtt.setSchedulingParameters( priority ); rtt.setReleaseParameters( period ); rtt.start(); // ...
Java RTS allows you to set thread priorities so you can precisely control the order of processing within your application. Also, by default, code in an RTT executes at a higher priority than the garbage collector. This setup eliminates the unpredictability associated with Java SE's collector, and eliminates most latency associated with garbage collection for your time-critical code. Let's take a brief look the real-time garbage collector in Java RTS.