JMU
Independent Threads
An Introduction with Examples in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Background
Some Informal Definitions
Two Distinct Situations
Motivation
Motivation (cont.)

The Indexer

javaexamples/threads_independent/v1/Indexer.java
        import java.io.*;
import java.util.*;

/**
 * An Indexer can be used to create a line index (as opposed to
 * the traditional page index) for a text file. The index
 * contains all of the words and the lines in which they appear.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Indexer
{
    private int                             minimumWordLength;    
    private Map<String, ArrayList<Integer>> index;
    private String                          title;    

    /**
     * Explicit Value Constructor.
     *
     * @param title  The title of the book (without the suffix)
     * @param minimumWordLength  The length of the shortest word to include
     */
    public Indexer(String title, int minimumWordLength)
    {
        this.title = title;        
        this.minimumWordLength = minimumWordLength;        
        index = new HashMap<String, ArrayList<Integer>>();
    }

    /**
     * Create the index.
     */
    public void createIndex()
    {
        int     lineNumber;        
        String  line;
        
        try
        {
            // Process the inpute file
            BufferedReader in = new BufferedReader(
                new FileReader(title+".txt"));

            lineNumber = 0;            
            while ((line = in.readLine()) != null)
            {
                String[] words = line.split("[*/\\.,;:?!(){} \t]");
                for (int i=0; i<words.length; i++)
                {
                    if (words[i].length() >= minimumWordLength) 
                    {
                        ArrayList<Integer> list = index.get(words[i]);
                        if (list == null) 
                        {
                            list = new ArrayList<Integer>();
                            index.put(words[i], list);
                        }
                        list.add(lineNumber);
                    }
                }
                ++lineNumber;
            }
            in.close();

            // Create the output file
            PrintWriter out = new PrintWriter(
                new FileOutputStream(title+".ndx"));
            List<String> keys = new ArrayList<String>(index.keySet());
            Collections.sort(keys);
            for (String key: keys)
            {
                List<Integer> list = index.get(key);                
                out.printf("%s\t", key);
                for (int i: list)
                {
                    out.printf("%d ", i);
                }
                out.printf("\n");
            }
            out.close();
        }
        catch (IOException ioe)
        {
            // Don't create an output file
        }
    }
}
        
Motivation (cont.)

The User Interface

javaexamples/threads_independent/v1/Lindex.java
        import java.io.*;

/**
 * A caommand-line application that creates a line-number index
 * of a text.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Lindex
{
    /**
     * The entry point of the application.
     *
     * @param args  The command line arguments (which are ignored)
     */
    public static void main(String[] args) throws IOException
    {
        String name;
        BufferedReader in = new BufferedReader(
            new InputStreamReader(System.in));

        System.out.print("Title: ");        
        while ((name = in.readLine()) != null)
        {
            Indexer indexer = new Indexer(name, 4);

            // Since this method can take a significant amount of time,
            // the UI may not be responsive.
            indexer.createIndex();

            System.out.print("Title: ");        
        }
    }
}
        
Motivation (cont.)
One Way to Use Threads in Java
One Way to Use Threads in Java (cont.)
Another Way to Use Threads in Java
A "Threaded" Indexer
javaexamples/threads_independent/v2/Indexer.java
        import java.io.*;
import java.util.*;

/**
 * An Indexer can be used to create a line index (as opposed to
 * the traditional page index) for a text file. The index
 * contains all of the words and the lines in which they appear.
 *
 * This version performs the indexeing in a separate thread of
 * execution.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 2.0
 */
public class Indexer implements Runnable
{
    private int                             minimumWordLength;    
    private Map<String, ArrayList<Integer>> index;
    private String                          title;    
    private Thread                          thread;
    

    /**
     * Explicit Value Constructor.
     *
     * @param title  The title of the book (without the suffix)
     * @param minimumWordLength  The length of the shortest word to include
     */
    public Indexer(String title, int minimumWordLength)
    {
        this.title = title;        
        this.minimumWordLength = minimumWordLength;        
        index = new HashMap<String, ArrayList<Integer>>();
    }

    /**
     * Create the index.
     */
    public void createIndex()
    {
        if (thread == null)
        {
            thread = new Thread(this);
            thread.start();
        }
    }

    /**
     * The code to execute in the separate thread
     * of execution.
     */
    public void run()
    {
        int     lineNumber;        
        String  line;
        
        try
        {
            // Process the inpute file
            BufferedReader in = new BufferedReader(
                new FileReader(title+".txt"));

            lineNumber = 0;            
            while ((line = in.readLine()) != null)
            {
                String[] words = line.split("[*/\\.,;:?!(){} \t]");
                for (int i=0; i<words.length; i++)
                {
                    if (words[i].length() >= minimumWordLength) 
                    {
                        ArrayList<Integer> list = index.get(words[i]);
                        if (list == null) 
                        {
                            list = new ArrayList<Integer>();
                            index.put(words[i], list);
                        }
                        list.add(lineNumber);
                    }
                }
                ++lineNumber;
            }
            in.close();

            // Create the output file
            PrintWriter out = new PrintWriter(
                new FileOutputStream(title+".ndx"));
            List<String> keys = new ArrayList<String>(index.keySet());
            Collections.sort(keys);
            for (String key: keys)
            {
                List<Integer> list = index.get(key);                
                out.printf("%s\t", key);
                for (int i: list)
                {
                    out.printf("%d ", i);
                }
                out.printf("\n");
            }
            out.close();
        }
        catch (IOException ioe)
        {
            // Don't create an output file
        }

        thread = null;
    }
    
}
        
Tracing a Multi-threaded Application

public class SlasherDriver
{
    public static void main(String[] args)
    {
	Slasher     plus, slash;

1       slash = new Slasher();
6       slash.setCount(3);
8       slash.start();
10      plus = new Slasher("+");
14      plus.setCount(2);
16      plus.start();
    }
}
  
public class Slasher implements Runnable
{
    private int         count;
    private String      symbol;
    private Thread      controlThread;

    public Slasher()
    {
2       this("/");
    }
    
    public Slasher(String symbol)
    {
3 11    this.symbol = symbol;
4 12    count = 0;
5 13    controlThread = new Thread(this);
    }

    public void run()
    {
A C E G for (int i=0; i<count; i++)  a c e
        {
B D F          System.out.print(symbol);  b d
        }
    }

    public void setCount(int count)
    {
7 15    this.count = count;
    }

    public void start()
    {
9 17    controlThread.start();
    }
}
  

Safe Construction
Daemon Threads
Priorities and Scheduling in Java