Java. Examples of solving tasks on threads of execution

Examples of solving tasks on threads of execution (Threads). Working with files in streams. Sorting in streams


Contents


Search other websites:




1. Task. Parallel integer arrays in threads

Task. The user enters a value into the array from the keyboard. Whereupon two threads are started. The first thread finds the maximum in the array, the second – the minimum. The calculation results are returned to the main() function.

Solution. This task is solved with the declaration of one class, in which the search for the minimum and maximum array element is implemented simultaneously. Optionally, you can implement two separate classes that will define the appropriate threads.

// A class that implements a child thread in a task
class ThreadMinMax implements Runnable {
  private Thread thr; // reference to the child thread
  private int[] AI;
  private int maximum; // maximum value
  private int minimum; // minimum value

  // Constructor - receives an array of integers
  public ThreadMinMax(int[] _AI) {
    // Array initialization
    AI = _AI;

    // Create a thread
    thr = new Thread(this, "Thread1.");

    // Run thread for execution
    thr.start();
  }

  // The method in which the thread execution code is defined
  // In our case, the code for finding the minimum value
  // and filling in the variable maximum is entered.
  public void run() {
    int max = AI[0];
    int min = AI[0];
    for (int i=1; i<AI.length; i++) {
      if (max<AI[i]) max = AI[i];
      if (min>AI[i]) min = AI[i];
    }
    maximum = max;
    minimum = min;
  }

  // Access methods for class fields
  public Thread getThread() { return thr; }
  public int getMax() { return maximum; }
  public int getMin() { return minimum; }
}

public class TrainThreads2 {

  public static void main(String[] args) {
    // 1. Declare the array under test
    int[] AI = { 2, 3, 4, 8, -1 };

    // 2. Create two child threads, get references to them
    ThreadMinMax t1 = new ThreadMinMax(AI);
    ThreadMinMax t2 = new ThreadMinMax(AI);

    // 3. Read the result
    try {
      // Waiting for the completion of threads t1, t2 is mandatory,
      // otherwise you can get zero values
      t1.getThread().join();
      t2.getThread().join();
    }
    catch (InterruptedException e) {
      System.out.println("Error.");
    }

    // Read the result after completion of threads t1, t2
    System.out.println("max = " + t1.getMax());
    System.out.println("min = " + t1.getMin());
  }
}

Program execution result

max = 8
min = -1

 

2. Task. Writing arrays of numbers to files in different threads. Runnable interface implementation

Task. Three integer arrays are given. Write these arrays to a file in parallel threads. Create a SaveAsThread class to represent a thread that writes an integer array to a file.

Solution. Thread encapsulation is implemented in the SaveAsThread class. The class contains the following components:

  • AI – an array to be written to a file in a stream;
  • filename – the name of the file into which the AI array is written;
  • threadName – the name of the current thread;
  • t – a reference to the Thread class that implements the current thread;
  • constructor SaveAsThread(), which receives as input parameters an array, file name and name of the current thread;
  • start() method to start the thread;
  • run() method in which the thread code is executed. This method is invoked when the start() method of the Thread class is called on the internal reference t.
import java.util.*;
import java.io.*;

// A class that represents a thread of writing an array of integers to a file
class SaveAsThread implements Runnable {
  private int[] AI; // writeable array
  private String filename; // the name of the file
  private String threadName; // the name of thread
  private Thread t; // reference to the current thread

  // Constructor - receives 3 parameters:
  // - AI - an array to be written to a file;
  // - filename - the name of the file into which the AI array must be written;
  // - threadName - the name of thread.
  public SaveAsThread(int[] AI, String filename, String threadName) {
    // Save the reference to array
    this.AI = AI;

    // Save the name of file
    this.filename = filename;

    // Save the name of thread
    this.threadName = threadName;

    // Create a thread using "SaveThread" name
    t = new Thread(this, "SaveThread");
  }

  // method that starts the current thread
  public void start() {
    t.start(); // invoke the run() method
  }

  // The run() method specifies the code for writing to the file
  public void run() {
    // Announce about the beginning of the thread execution
    System.out.println("Begin thread: " + threadName);

    try {
      // Create relation with the filename: fOut -> filename
      FileOutputStream fOut = new FileOutputStream(filename);

      // Create relation fOut: ps -> fOut -> filename
      PrintStream pS = new PrintStream(fOut);

      // Write array AI to file
      pS.println(AI.length);
      for (int i=0; i<AI.length; i++) {
        pS.println(AI[i]);
      }

      // Close streams
      pS.close();
      fOut.close();
    }
    catch (IOException e) {
      // Display an error message
      System.out.println("Error: " + e.getMessage());
    }

    // Report the end of the thread
    System.out.println("End thread: " + threadName);
  }
}

public class Threads {

  public static void main(String[] args) throws IOException {
    // Writing arrays to different files in different threads
    // 1. Create three integer arrays
    int[] AI1 = { 2, 4, 3, 8, 9, 11, 7 };
    int[] AI2 = { 1, 8, 7, 6, 3 };
    int AI3[] = { 7, 7, 9, 9, 4, 2 };

    // 2. Create three threads
    SaveAsThread t1 = new SaveAsThread(AI1, "AI1.txt", "t1");
    SaveAsThread t2 = new SaveAsThread(AI2, "AI2.txt", "t2");
    SaveAsThread t3 = new SaveAsThread(AI3, "AI3.txt", "t3");

    // 3. Run threads to execution
    t1.start();
    t2.start();
    t3.start();
  }
}

Program result

Begin thread: t1
End thread: t1
Begin thread: t2
Begin thread: t3
End thread: t2
End thread: t3

After starting the program, three files will be created with the names “AI1.txt”, “AI2.txt”, “AI3.txt”, which contain the values of the elements of the corresponding arrays.

 

3. Task. Reading arrays of numbers from a file

This task is the reverse of the previous task.

Task. Three files with the names “AI1.txt”, “AI2.txt”, “AI3.txt” are specified. Each of the files contains integer arrays according to the following format:

N
number1
number2
...
numberN

here

  • N – the number of numbers that are saved in the file;
  • number1, number2, …, numberN – numbers.

Solution. To solve the task, a special class ReadFileAsThread is declared, which contains the following components:

  • AI – an array that is read from a file;
  • filename – the name of the file from which it is needed to read data into the AI array;
  • thr – a reference to the Thread class. This link points to the current thread;
  • a constructor that receives a file name and a stream name as input parameters;
  • method Start() – designed to start a thread from the client code. This method calls the start() method of the Thread class at thr reference. As a result, the run() method is called;
  • get() method – method for accessing the AI array from external client code (main() function).

Another Threads class implements the main() function, which demonstrates how the ReadFileAsThread class works. 3 threads are created. Arrays are read. The read arrays are displayed on the screen.

The execution of the program provides for the presence of files “AI1.txt”, “AI2.txt”, “AI3.txt”.

import java.util.*;
import java.io.*;

// A class that encapsulates the thread of reading an array of numbers from a file.
// The class extends the capabilities of the Thread class
class ReadFileAsThread extends Thread {
  private int[] AI; // array to read from file
  private String filename; // the name of file
  private Thread thr; // reference to the current thread

  // Constructor
  public ReadFileAsThread(String filename, String threadName) {
    // Save the name of file
    this.filename = filename;

    // Create a thread using threadName
    thr = new Thread(this, threadName);
  }

  // Run the thread
  public void Start() {
    thr.start(); // The run() method is called
  }

  // Direct thread execution code
  public void run() {
    // 1. Notify about the beginning of stream execution - reading from a file
    System.out.println("Begin thread: " + thr.getName());

    FileInputStream fInput;
    try {
      // 2. Associate filename with fInput instance: fInput <- filename
      fInput = new FileInputStream(filename);

      // 3. Bind an instance of the Scanner class to an instance of fInput:
      // scanner <- fInput <- filename
      Scanner scanner = new Scanner(fInput);

      // 4. Declare an additional variables
      int count; // The number of items in the array

      // 5. Read the number of array items
      count = scanner.nextInt();

      // 6. Allocate memory for array AI
      AI = new int[count];

      // 7. Read numbers
      for (int i=0; i<AI.length; i++)
        AI[i] = scanner.nextInt();

      // 8. Close streams
      scanner.close();
      fInput.close();
    } 
    catch (IOException e) {
      // Display the error message
      System.out.println("Error: " + e.getMessage());
    }

    // Report the completion of thread execution - read from file file
    System.out.println("End thread: " + thr.getName());
  }

  // Access method to array AI
  public int[] get() { return AI; }
}

public class Threads {

  public static void main(String[] args) throws IOException {
    // Writing arrays to different files in different threads
    // 1. Create three references to integer arrays
    int[] AI1 = null;
    int[] AI2 = null;
    int AI3[] = null;

    // 2. Create three threads
    ReadFileAsThread t1 = new ReadFileAsThread("AI1.txt", "t1");
    ReadFileAsThread t2 = new ReadFileAsThread("AI2.txt", "t2");
    ReadFileAsThread t3 = new ReadFileAsThread("AI3.txt", "t3");

    // 3. Run threads
    t1.start();
    t2.start();
    t3.start();

    // 4. Wait for the threads to finish to get the correct result.
    // The join() method is used for this.
    try {
      t1.join();
      t2.join();
      t3.join();
    }
    catch (InterruptedException e) {
      // If there is an error, then display the message
      System.out.println("Error: " + e.getMessage());
      return;
    }

    // 4. Read arrays
    AI1 = t1.get();
    AI2 = t2.get();
    AI3 = t3.get();

    // 5. Display arrays for control
    System.out.print("AI1 = [ ");
    for (int d : AI1)
      System.out.print(d + " ");
    System.out.println(" ]");

    System.out.print("AI2 = [ ");
    for (int d : AI2)
      System.out.print(d + " ");
    System.out.println(" ]");

    System.out.print("AI3 = [ ");
    for (int d : AI3)
      System.out.print(d + " ");
    System.out.println(" ]");
  }
}

The result of the program

Begin thread: t2
Begin thread: t1
Begin thread: t3
End thread: t3
End thread: t1
End thread: t2
AI1 = [ 2 4 3 8 9 11 7 ]
AI2 = [ 1 8 7 6 3 ]
AI3 = [ 7 7 9 9 4 2 ]

 

4. Task. A thread of strings of type String. Sorting an array of strings in several threads by different algorithms

Task. Implement following sorting algorithms:

  • insertion sorting;
  • selection sorting;
  • bubble sorting.

Demonstrate sorts on arrays of strings of type String[]. Each kind of sort must run on a separate thread.

Solution. To implement sorting algorithms, the program implements three classes:

  • SelectionSortThread – encapsulates the thread in which sorting is performed by the selection method;
  • InsertionSortThread – encapsulates the thread in which the insertion sort is performed;
  • BubbleSortThread – encapsulates a thread in which bubble sorting is performed.

All classes have similar internal variables and methods:

  • AS – sortable array;
  • t – a reference to the current thread of type Thread;
  • constructor;
  • start() method – starts the thread for execution;
  • run() method – contains the thread execution code;
  • get() method – provides access to the internal AS array;
  • getThread() method – required to access a thread t of type Thread.

 

// A class that encapsulates a stream
// that sorts lines by selection method in descending order.
class SelectionSortThread extends Thread {
  // Internal class fields
  private String[] AS; // array of lines
  private Thread t; // reference to the current thread

  // Constructor, which receives parameters:
  // - array of strings from outside;
  // - the name of current thread.
  public SelectionSortThread(String[] AS, String threadName) {
    // Save reference to external array
    this.AS = AS;

    // Create a thread
    t = new Thread(this, threadName);
  }

  // Method that starts the thread
  public void Start() {
    t.start(); // Invoke methods of Thread class
  }

  // Method that runs on a thread
  public void run() {
    // Sort lines using selection sorting algorithm

    // 1. Announce the beginning of the sorting
    System.out.println("Begin => " + t.getName());

    // 2. Declare an additional internal variables
    int i, j, k;
    String s;

    // 3. The loop of selection sorting algorithm in descending order
    for (i=0; i<AS.length; i++) {
      // i - current step
      k = i;

      // Finding the largest (maximum) item
      s = AS[i];

      for (j=i+1; j<AS.length; j++)
        if (AS[j].compareTo(s)>0) {
          k = j; // index of the maximum item
          s = AS[j];
        }

      // Swap the maximum element with AS[i]
      AS[k] = AS[i];
      AS[i] = s;
    }

    // 4. Report the completion of the stream
    System.out.println("End => " + t.getName());
  }

  // Access method to the array AS
  public String[] get() { return AS; }

  // Method of access to a thread t
  public Thread getThread() { return t; }

  // Method that displays the AS array on the screen
  public void Print() {
    System.out.print(t.getName() + " = [ ");
    for (String s : AS)
      System.out.print(s + " ");
    System.out.println(" ]");
  }
}

// A class that encapsulates a stream in which an array of strings is sorted by insertion method.
// A thread is created by inheriting from the Thread class.
// Sorting occurs in descending order of elements.
class InsertionSortThread extends Thread {

  // Internal class fields
  private String[] AS; // array of strings
  private Thread t; // current thread

  public InsertionSortThread(String[] AS, String threadName) {
    // Save reference to external array
    this.AS = AS;

    // Create a stream
    t = new Thread(this, threadName);
  }

  // Method that starts a thread from client code
  public void Start() {
    t.start(); // implicit call of the run() method
  }

  // Method that starts a thread from client code
  public void run() {
    // Here you need to implement sorting by the insert method
    // 1. Inform about the start of sorting
    System.out.println("Begin => " + t.getName());

    // 2. Declare internal variables
    int i, j;
    String s;

    // 3. The loop of insertion sorting algorithm.
    for (i=0; i<AS.length; i++) {
      // i - number of step

      s = AS[i];

      // Finding the place of an element in a sequence
      for (j=i-1; j>=0 && AS[j].compareTo(s)<0; j--) {
        // move the item to the right as possible
        AS[j+1] = AS[j];
      }
      AS[j+1] = s;
    }

    // 4. Report the completion of sorting (stream)
    System.out.println("End => " + t.getName());
  }

  // Access method to the array AS
  public String[] get() { return AS; }

  // Method of access to thread t
  public Thread getThread() { return t; }

  // Method to display the AS array
  public void Print() {
    System.out.print(t.getName() + " = [ ");
    for (String s : AS)
      System.out.print(s + " ");
    System.out.println(" ]");
  }
}

// The class that encapsulates the stream in which bubble sort occurs.
// Sorting strings in descending order.
// The class implements the Runnable interface
class BubbleSortThread extends Thread {
  // Internal variables of the class
  private String[] AS; // array of strings
  private Thread t; // reference to the current string

  // Constructor. Receives two parameters:
  // - array of strings;
  // - the name of the current string.
  public BubbleSortThread(String[] AS, String threadName) {
    // Save external array
    this.AS = AS;

    // Create a new thread
    t = new Thread(this, threadName);
  }

  // Method that starts a thread for execution
  public void Start() {
    t.start();
  }

  // Method in which the thread is executed
  public void run() {

    // Bubble sorting
    // 1. Inform about the start of sorting
    System.out.println("Begin => " + t.getName());

    // 2. Declare the internal variables
    int i, j;
    String s;

    // 3. Sorting loop
    for (i=0; i<AS.length; i++) {
      // i - number of step

      for (j=AS.length-1; j>i; j--) {
        // internal loop
        // sorting by descending
        if (AS[j-1].compareTo(AS[j])<0) {
          s = AS[j];
          AS[j] = AS[j-1];
          AS[j-1] = s;
        }
      }
    }

    // 4. Report end of sort
    System.out.println("End => " + t.getName());
  }

  // Access method to the array AS
  public String[] get() { return AS; }

  // Access method to the thread t
  public Thread getThread() { return t; }

  // Method that prints the AS array to the screen
  public void Print() {
    System.out.print(t.getName() + " = [ ");
    for (String s : AS)
      System.out.print(s + " ");
    System.out.println(" ]");
  }
}

// A class that implements the main () function,
// in which the work of threads is tested
public class Threads {

  public static void main(String[] args) {

    // Demonstration of sorting arrays of strings in different streams
    // 1. Declare three arrays of strings. Arrays have the same values
    String[] AS1 = { "abc", "def", "bcd", "dsd", "aff", "jkl", "ffg"};
    String[] AS2 = { "abc", "def", "bcd", "dsd", "aff", "jkl", "ffg"};
    String[] AS3 = { "abc", "def", "bcd", "dsd", "aff", "jkl", "ffg"};

    // 2. Declare instances of thread classes
    SelectionSortThread t1 = new SelectionSortThread(AS1, "t1:SelectionSort");
    InsertionSortThread t2 = new InsertionSortThread(AS2, "t2:InsertionSort");
    BubbleSortThread t3 = new BubbleSortThread(AS3, "t3:BubbleSort");

    // 3. Run threads t1, t2, t3 in parallel
    t1.Start();
    t2.Start();
    t3.Start();

    // 4. Wait for the end of threads t1, t2, t3 to get the correct result
    try {
      t1.getThread().join();
      t2.getThread().join();
      t3.getThread().join();
    }
    catch (InterruptedException e) {
      // If there is an error, then display the message
      System.out.println("Error: " + e.getMessage());
      return;
    }

    // 5. Display sorted arrays to screen
    t1.Print();
    t2.Print();
    t3.Print();
  }
}

After launching for execution, the program produced the following result

Begin => t2:InsertionSort
Begin => t3:BubbleSort
Begin => t1:SelectionSort
End => t3:BubbleSort
End => t2:InsertionSort
End => t1:SelectionSort
t1:SelectionSort = [ jkl ffg dsd def bcd aff abc ]
t2:InsertionSort = [ jkl ffg dsd def bcd aff abc ]
t3:BubbleSort = [ jkl ffg dsd def bcd aff abc ]

 


Related topics