pixel
pixel
header

    October 29, 2002    

In this Issue

imageJava Programming Language Basics
imageJava Bits
imageMaking Sense of the Java Class Libraries
imageProgram Challenge
imageFor More Information

Pixel

Java Programming Language Basics

How to Use Threads

The Java platform was designed from the start to be a multithreaded environment. While your main program is executing, other tasks like garbage collection and event handling are done in the background. Mentally, you can think of these other tasks as threads. They happen to be system-managed threads, but nonetheless, they are threads. Threads enable you to define isolated tasks that happen independently of each other. The system then swaps tasks in and out of the CPU so that (externally) it appears they are all running simultaneously.

When you need to do multiple tasks in your own program, you, too, can work with multiple threads. These threads can be ones you create yourself, or you can interact with the system threads.

You do these multiple tasks using several different classes and interfaces:

  • java.util.Timer class
  • javax.swing.Timer class
  • Thread class
  • Runnable interface

For simple tasks that typically need to repeat, you can work with the java.util.Timer class to say "Do this task every half second." Keep in mind that most system routines work with milliseconds. A half second is 500 milliseconds.

The task you want the Timer to perform is defined in a java.util.TimerTask instance, where its run method contains the task to perform. This is demonstrated in the Hi class, where the String "Hi" is printed to the console repeatedly, until you press the Enter key.

import java.util.*;

public class Hi {
public static void main(String args[])
throws java.io.IOException {
TimerTask task = new TimerTask() {
public void run() {
System.out.println("Hi");
}
};
Timer timer = new Timer();
timer.schedule(task, 0, 500);
System.out.println("Press ENTER to stop");
System.in.read(new byte[10]);
timer.cancel();
}
}

The way the Java Runtime Environment (JRE) works is that as long as there is a thread running, the program won't exit. So, once cancel is called, there are no other user threads running and the program exits. There are some system threads running, like the garbage collector. These system threads are also called daemon threads. The existence of daemon threads does not prevent the runtime environment from shutting down; Only non-daemon threads prevent that.

The javax.swing.Timer class works similarly to the java.util.Timer class, with a couple of differences of note. First, the task to run is defined by an implementation of the ActionListener interface. Second, the task executes within the event-handling thread, not outside of it like the java.util.Timer class. This is important because of how the Swing component set was designed.

If you aren't familiar with Swing, it is the set of graphics components available to Java programs. Swing was designed to be what is called single-threaded. That means that all access to the internal contents of the Swing classes must be done within a single thread. That specific thread is the event-handling thread. So, for example if you wanted to change the text of a label component, you couldn't just call the setText method of JLabel. Instead, you would have to make sure that the setText call happens in the event-handling thread, and that is where the javax.swing.Time class comes in handy.

To demonstrate this second case, the following program displays the value of an increasing counter. Every half second the counter value is increased and the new value is displayed.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Count {
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
final JLabel label = new JLabel("", JLabel.CENTER);
label.setFont(new Font("Serif", Font.PLAIN, 36));
contentPane.add(label, BorderLayout.CENTER);
ActionListener listener = new ActionListener() {
int count = 0;
public void actionPerformed(ActionEvent e) {
count++;
label.setText(Integer.toString(count));
}
};
Timer timer = new Timer(500, listener);
timer.start();
frame.setSize(300, 100);
frame.show();
}
}

The program above produces the following:

Count

In cases where there isn't a simple repeating task to be done, the java.lang.Thread class comes into play. It allows you to control the raw functionality yourself. By creating a subclass of Thread, you can have the system go off and do a long-running task, like reading a file from over the network, without blocking the execution of the rest of your program. That long running task would be defined in the run method.

The run method used by Thread and TimerTask is actually part of an interface: java.lang.Runnable. While you could always subclass Thread to define the task to be done, if you aren't adding any behavior to the subclass (besides the task to be done) the more appropriate way to design the system is to define the task to be done in an implementation of the Runnable interface. Then, you pass the implementation to the Thread constructor. And, when you start the thread up, that Runnable is what is executed.

The second way is to subclass Thread and implement the run method in the subclass, or implement the run method in a class that implements Runnable and pass that implementation on to the Thread constructor.

You may ask yourself what is the difference. The Java programming language only supports single inheritance. If your design calls for a different superclass besides Thread, you can have your class implement Runnable, and it will have its task to execute. Otherwise, you subclass Thread to define its own run method, adding no particular set of operations in the process.

For this third case of subclassing Thread, the following program creates a new thread to count the number of characters in a particular URL whose value is passed in from the command line. While that is going on, the fourth case of implementing Runnable is demonstrated, printing out a repeated message. Notice in this latter case of implementing Runnable, you must provide the code to repeat the message. You have to both sleep for the allotted time and do the action. Compare that to the use of Timer, in both cases. The final piece of the program has you read a line from the command to trigger the program ending. Notice that while the system is reading from the URL and printing the message, you can always press Enter to end the program.

import java.io.*;
import java.net.*;

public class Both {
public static void main(String args[]) {
final String urlString = args[0];
final String message = args[1];
Thread thread1 = new Thread() {
public void run() {
try {
URL url = new URL(urlString);
URLConnection connection =
url.openConnection();
InputStreamReader isr = new
InputStreamReader(
connection.getInputStream());
BufferedReader reader = new BufferedReader(isr);
int count = 0;
while (reader.read() != -1) {
count++;
}
System.out.println("Size is : "
+ count);
reader.close();
} catch (MalformedURLException e) {
System.err.println("Bad URL: "
+ urlString);
} catch (IOException e) {
System.err.println("I/O Problems");
}
}
};
thread1.start();
Runnable runnable = new Runnable() {
public void run() {
while(true) {
System.out.println(message);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
};
Thread thread2 = new Thread(runnable);
thread2.start();
try {
System.out.println("Press ENTER to stop");
System.in.read(new byte[10]);
} catch (IOException e) {
System.out.println("I/O problems");
}
System.exit(0);
}
}

While there are many ways of working with threads, which technique you use is up to you and your circumstances. While you usually don't have to learn everything about the Java programming language and its core libraries to become a productive Java programmer, threading is an exception. The sooner you can understand how threads work and how to use them, the sooner you'll come to understand how Java programs work and interact.

Pixel
Pixel

Java Bits

Working with Boolean Statements

A boolean value is a primitive data type that has a value of either true or false. Boolean statements allow you to consider several conditions in one programming decision. To determine if conditions are true or false, boolean expressions frequently use the following operators:

  • && to mean AND
  • || to mean OR
  • ! to mean NOT
  • ^ to mean XOR

For example, in a program to determine overtime pay, the application must first determine whether the employee's work hours exceeded 40 hours for a particular week and for a particular type of job position:

if ((hours > 40) && (position.equals(
"salesClerk") ||
(position.equals("stockPerson")))
System.out.println(
"Employee receives overtime pay.");
else
System.out.println(
"Employee receives regular pay.");

The problem above is stating that if the hours worked are more than 40, and the job position is a sales clerk or a stock person, then print the statement, "Employee receives overtime pay." Otherwise, print the statement, "Employee receives regular pay."

Sometimes you may want to declare boolean variables first, then use them in a boolean expression to test conditions:

boolean isSaturday = day.equals("Saturday");
boolean isDayLight = hour < 19 && hour > 5;

if(isSaturday && isDayLight)
System.out.println("Go play at the beach");
if (isSaturday && !isDayLight)
System.out.println("Sleep until Sunday.");
Boolean

In the example above, the first boolean variable isSaturday is true only if a String Saturday is returned. The second boolean variable isDayLight defines the condition for daylight, and returns true only if these hourly conditions are met.

Pixel
Pixel

Making Sense of the Java Class Libraries

The JOptionPane Class

Pop-up dialog boxes are useful GUI components that can be used to alert users to problems, request information, or provide instruction. The Swing API provides a JOptionPane class that allows you to create simple dialog boxes by calling a static method, or create more elaborate dialogs containing text fields and buttons.

There are four basic types of JOptionPane dialog boxes:

  • Input dialog
  • Confirm dialog
  • Message dialog
  • Option dialog

You can create JOptionPane dialog boxes either by calling one of the JOptionPane constructors, or by calling one of the JOptionPane static methods:

  • showConfirmDialog: Ask a confirming question, like Yes/No/Cancel.
  • showInputDialog: Prompt for input.
  • showMessageDialog: Inform the user that something has happened.
  • showOptionDialog: A combination of the above three.
JOptionPane

The JOptionPane objects are not standalone containers. Instead, they exist inside a JDialog or JInternalFrame object that the static methods create and associate automatically.

When an application runs and the dialog pops up, unless a thread is implemented, no other action can be taken within the application until the dialog is dealt with, either by entering information, clicking a button, or closing the dialog box.

To create a message dialog that warns the user that the requested file doesn't exist, for instance, call the showMessageDialog static method:

JOptionPane.showMessageDialog(null, 
"Requested file cannot be found.",
null, JOptionPane.ERROR_MESSAGE );

or a dialog to confirm information:

JOptionPane.showConfirmDialog(null,
"Do you want to Exit?",
null, JOptionPane.YES_NO_OPTION );

JOptionPane dialog boxes serve many useful purposes from collecting data from the user to providing warnings and information.

Pixel
Pixel

Program Challenge

Create the Counter Application

Create a program that displays a number in the middle of the screen, and has four buttons.

  • The first button causes the number to increment its value every half second.
  • The second button causes the number to decrement its value every half second. The value can be incrementing or decrementing in one direction at a time.
  • The third button causes the incrementing/decrementing behavior to stop.
  • The fourth button resets the number to 0.

See a possible solution to Challenge:

Pixel
Pixel

For More Information

The Java FAQ -- Threads

Multithreaded Swing Applications

Creating a Threaded Slide Show Applet

Lesson: Threads: Doing Two or More Tasks At Once

Why Use Threads?

How to Make Dialogs

Class JOptionPane

Pixel
Pixel

Program Challenge Solution

See one possible solution to the October Program Challenge:

Pixel
Pixel

Downloading the Java 2 Platform

For most Java development, you need the class libraries, compiler, tools, and runtime environment provided with the Java 2, Standard Edition (J2SE) development kit.

Pixel
Pixel

Reader Feedback

  Very worth reading    Worth reading    Not worth reading 

If you have other comments or ideas for future newsletters, please type them here:

 

Have a question about Java programming? Use Java Online Support.

Pixel
Pixel
Pixel

Subscribe to the following newsletters for the latest information about technologies and products in other Java platforms:

- Core Java Technologies Newsletter. Learn about new products, tools, resources, and events of interest to developers working with core Java technologies.
- Wireless Developer Newsletter. Learn about the latest releases, tools, and resources for developers working on wireless and Java Card technologies and applications.
- Core Java Technologies Tech Tips (formerly JDC Tech Tips) Get expert tips, sample code solutions, and techniques for developing in the Java 2 Platform, Standard Edition (J2SE)
You can subscribe to these and other JDC publications on the JDC Newsletters and Publications page

IMPORTANT: Please read our Terms of Use, Privacy, and Licensing policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/
http://developer.java.sun.com/berkeley_license.html


Comments? Send your feedback on the Java Technology Fundamentals Newsletter to: dana.nourie@sun.com

Go to the subscriptions page to subscribe or unsubscribe to this newsletter.

ARCHIVES: You'll find the Java Technology Fundamentals Newsletter archives at:
http://java.sun.com/developer/onlineTraining/new2java/supplements/


Copyright 2002 Sun Microsystems, Inc. All rights reserved. 901 San Antonio Road, Palo Alto, California 94303 USA.

Sun, Sun Microsystems, Java, J2SE are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.

Sun Microsystems, Inc.
image
image