Java concurrent programming example of two: get and set thread information

  • 2020-04-01 03:33:24
  • OfStack

The Thread class contains several properties that represent information that helps us identify threads, observe their status, control their priorities, and so on. These threads include the following:

ID: this property represents the unique identity of each thread;
Name: this property stores the Name of each thread;
Priority: this property stores the Priority of each Thread object. Thread priorities range from 1 to 10, with 1 representing the lowest priority and 10 the highest. It is not recommended to change the priority of a thread, but if you do, you can try it.
Status: this property stores the state of the thread. Threads have six different states: new, runnable, blocked, waiting, time waiting, or terminated. The state of a thread must be one of these.

In this section, we will develop a program that creates ten new threads and sets the name and priority of each thread. The thread is then executed, observing the status of the thread until the thread completes its execution. Just to be clear, these threads are still times tables for counting a number.

learning

Follow these steps to implement the example:

1. Create a class called Calculator that implements the Runnable interface. The code is as follows:


public class Calculator implements Runnable {

2. Declare a private plastic property named number, and implement the constructor of the class to initialize the property just declared. The code is as follows:


private int number; public Calculator(int number) {
    this.number = number;
}

3. Implement the run() method, which is the instruction that runs when the thread we created executes, so it is used to calculate The Times table. The specific code is as follows:


@Override
public void run() {
    for (int i = 0; i < 10; i++) {
        System.out.printf("%s: %d * %d = %dn",
                Thread.currentThread().getName(),
                number, i, i * number);
    }
}

4. Now, let's implement the main class of the sample application. Create a class named Main and add the Main method to the class. The code is as follows:

public class Main {
    public static void main(String[] args) {

5. Create two arrays of ten elements, one of type Thread and one of type thread.state, and initialize them all. These two arrays, one for the threads that we will execute and the other for the state of those threads. The code is as follows:


Thread[] threads = new Thread[10];
Thread.State[] status = new Thread.State[threads.length];

6. Create ten Calculator objects and initialize each with a different number. Use these Calculator objects to create ten Thread objects, which are stored in the created array above. At the same time, set the priority of these threads, five to the highest priority; Set five as the lowest priority. The code is as follows:


for (int i = 0; i < threads.length; i++) {
    threads[i] = new Thread(new Calculator(i));
    if ((i % 2) == 0) {
        threads[i].setPriority(Thread.MAX_PRIORITY);
    } else {
        threads[i].setPriority(Thread.MIN_PRIORITY);
    }
    threads[i].setName("Thread-" + i);
}

7. Create a PrintWriter object to record changes in thread state to a file. The code is as follows:

try (FileWriter file = new FileWriter("D:\thread.log");
     PrintWriter pw = new PrintWriter(file)) {

Java7 syntax is used here, so upgrade the JDK to version 7 and set the compiler to Java7. Otherwise you will report a syntax error.

Write the status of all threads to a file. Now, the current state should be NEW. The code is as follows:


for (int i = 0; i < threads.length; i++) {
    Thread thread = threads[i];
    pw.println("Main: Status of Thread " + i +
            " : " + threads[i].getState());
    status[i] = threads[i].getState();
}

Start all threads. Code:

for (int i = 0; i < threads.length; i++) {
    threads[i].start();
}

10. On the other hand, we monitor threads until they finish executing. If we detect a change in the thread's state, we immediately write the thread state to a file. The code is as follows:

boolean finish = false; while (!finish) {
    for (int i = 0; i < threads.length; i++) {
        if (threads[i].getState() != status[i]) {
            writeThreadInfo(pw, threads[i], status[i]);
            status[i] = threads[i].getState();
        }
    }
    finish = true;
    for (int i = 0; i < threads.length; i++) {
        finish = finish
                && (threads[i].getState() == Thread.State.TERMINATED);
    }
}

11. Implement the writeThreadInfo method, which writes the thread's ID, name, priority, old state, and new state to a file. The code is as follows:


/**
 * Outputs the state of a thread to a file.
 *
 * @param pw     PrintWriter object
 * @param thread A thread object that needs to output state
 * @param state  The old state of the thread
 */
private static void writeThreadInfo(PrintWriter pw,
                                  Thread thread, Thread.State state) {
    pw.printf("Main : Id %d = %sn", thread.getId(), thread.getName());
    pw.printf("Main : Priority: %dn", thread.getPriority());
    pw.printf("Main : Old State: %sn", state);
    pw.printf("Main : New State: %sn", thread.getState());
    pw.printf("Main : ********************************n");
}

12. Run the example, then open the thread.log file to see the evolution of all threads.

Know why

The following is a snippet of the contents of the thread.log file. As you can see from the contents of the file, high-priority threads generally finish execution earlier than low-priority threads. In addition, you can see the state evolution of each thread.


Main : ********************************
Main : Id 11 = Thread-2
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: TERMINATED
Main : ********************************
Main : Id 13 = Thread-4
Main : Priority: 10
Main : Old State: BLOCKED
Main : New State: TERMINATED
Main : ********************************
Main : Id 14 = Thread-5
Main : Priority: 1
Main : Old State: BLOCKED
Main : New State: TERMINATED
Main : ********************************

The following is a snippet of the console's output. The output is The Times table calculated by each thread, and the calculation process of all threads. At the same time, you can see the evolution of each thread at a more granular level from here.


Thread-8: 8 * 2 = 16
Thread-8: 8 * 3 = 24
Thread-8: 8 * 4 = 32
Thread-6: 6 * 0 = 0
Thread-6: 6 * 1 = 6
Thread-6: 6 * 2 = 12
Thread-6: 6 * 3 = 18
Thread-6: 6 * 4 = 24
Thread-6: 6 * 5 = 30
Thread-6: 6 * 6 = 36
Thread-6: 6 * 7 = 42
Thread-6: 6 * 8 = 48
Thread-6: 6 * 9 = 54
Thread-5: 5 * 0 = 0
Thread-5: 5 * 1 = 5
Thread-5: 5 * 2 = 10
Thread-5: 5 * 3 = 15
Thread-5: 5 * 4 = 20

The Thread class has all the attributes you need to store Thread information. The Java virtual machine USES thread priorities to schedule one thread at a time to use the CPU, and to set the state of each thread according to its condition.

If the name of the Thread is not set, the Java virtual machine USES this format to assign a name, thread-xx, where XX is a number. We cannot change the ID of the thread or the state of the thread. The Thread class also does not implement the setId() and setStatus() methods to allow these changes.

endless

In this section, you learned how to use Thread objects to access Thread information. In fact, the Runnable implementation class also runs us to access this information. CurrentThread (), the static method of the Thread class, gets the object of the Runnable implementation class being executed to access the Thread's information.

Note that setPriority() throws an exception named IllegalArgumentException if you try to set priorities beyond 1 to 10,

si

This article is a translation from the Java7 Concurrency Cookbook (D jago to Java7 Concurrency examples) and is intended for use only as a learning material. Not to be used in any commercial activities without authorization.

Small has becomes

The complete code for the Calculator class


package com.diguage.books.concurrencycookbook.chapter1.recipe2; /**
 * Date: 2013-09-13
 * Time: 19:49
 */
public class Calculator implements Runnable {
    private int number;     public Calculator(int number) {
        this.number = number;
    }     @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.printf("%s: %d * %d = %dn",
                    Thread.currentThread().getName(),
                    number, i, i * number);
        }
    }
}

The complete code for the Main class


package com.diguage.books.concurrencycookbook.chapter1.recipe2; import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter; /**
 * Date: 2013-09-13
 * Time: 19:51
 */
public class Main {
    public static void main(String[] args) {
        Thread[] threads = new Thread[10];
        Thread.State[] status = new Thread.State[threads.length];         for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Calculator(i));
            if ((i % 2) == 0) {
                threads[i].setPriority(Thread.MAX_PRIORITY);
            } else {
                threads[i].setPriority(Thread.MIN_PRIORITY);
            }
            threads[i].setName("Thread-" + i);
        }         try (FileWriter file = new FileWriter("D:\thread.log");
             PrintWriter pw = new PrintWriter(file)) {
            for (int i = 0; i < threads.length; i++) {
                Thread thread = threads[i];
                pw.println("Main: Status of Thread " + i +
                        " : " + threads[i].getState());
                status[i] = threads[i].getState();
            }             for (int i = 0; i < threads.length; i++) {
                threads[i].start();
            }             boolean finish = false;             while (!finish) {
                for (int i = 0; i < threads.length; i++) {
                    if (threads[i].getState() != status[i]) {
                        writeThreadInfo(pw, threads[i], status[i]);
                        status[i] = threads[i].getState();
                    }
                }
                finish = true;
                for (int i = 0; i < threads.length; i++) {
                    finish = finish
                            && (threads[i].getState() == Thread.State.TERMINATED);
                }
            }         } catch (IOException e) {
            e.printStackTrace();
        }
    }     /**
     * Outputs the state of a thread to a file.
     *
     * @param pw     PrintWriter object
     * @param thread A thread object that needs to output state
     * @param state  The old state of the thread
     */
    private static void writeThreadInfo(PrintWriter pw,
                                      Thread thread, Thread.State state) {
        pw.printf("Main : Id %d = %sn",
                    thread.getId(), thread.getName());
        pw.printf("Main : Priority: %dn", thread.getPriority());
        pw.printf("Main : Old State: %sn", state);
        pw.printf("Main : New State: %sn", thread.getState());
        pw.printf("Main : ********************************n");
    }
}


Related articles: