JavaRush /Java Blog /Random EN /Multithreading: What Thread Class Methods Do

Multithreading: What Thread Class Methods Do

Published in the Random EN group
Hello! Today we continue to talk about multithreading. Let's take a look at the Thread class and how its several methods work. Previously, when we studied class methods, we most often simply wrote it like this: “name of the method” -> “what it does.”
Multithreading: what the methods of the Thread class do - 1
This will not work with Thread methods :) Their logic is more complicated, and without several examples it’s impossible to understand.

Thread.start() method

Let's start with repetition. As you probably remember, you can create a thread by inheriting your class from the class Threadand overriding the method in it run(). But, of course, it won’t start on its own. To do this, we call the method on our object start(). Multithreading: what the methods of the Thread class do - 2Let's remember the example from the previous lecture:
public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("Выполнен поток " + getName());
   }
}


public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
Please note: to start a thread, you must call the special methodstart(), not therun()! This is an easy mistake to make, especially when first learning multithreading. If in our example you call a method on an object 10 timesrun()instead ofstart(), the result will be like this:
public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
Thread-0 thread executed Thread-1 thread executed Thread-2 thread executed Thread-3 thread executed Thread-4 thread executed Thread-5 thread executed Thread-6 thread executed Thread-7 thread executed Thread-8 thread executed Thread-9 thread executed Look at the output sequence: everything goes strictly in order. Strange, right? We are not used to this, because we already know that the order in which threads are launched and executed is determined by the superintelligence inside our operating system - the thread scheduler. Maybe I was just lucky? Of course, it's not a matter of luck. You can verify this by running the program a couple more times. The point is that calling a method directlyrun()has nothing to do with multithreading. In this case, the program will be executed in the main thread - the one in which the method is executedmain(). It will simply output 10 lines sequentially to the console and that's it. No 10 threads will start. Therefore, remember for the future and constantly check yourself. If you want it to be donerun(), call itstart(). Let's move on.

Thread.sleep() method

To pause the execution of the current thread for some time, use the sleep(). Multithreading: what the methods of the Thread class do - 3The method sleep()takes as a parameter the number of milliseconds, that is, the time for which the thread needs to be put to sleep.
public class Main {

   public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();

       Thread.sleep(3000);

       System.out.println(" - Сколько я проспал? \n - " + ((System.currentTimeMillis()-start)) / 1000 + " секунды");

   }
}
Console output: - How long did I sleep? - 3 seconds Please note: the method sleep()is static: it puts the current thread to sleep. That is, the one that is working at the moment. Another important nuance: the flow in the sleep state can be interrupted. In this case, an exception will occur in the program InterruptedException. We'll look at an example below. By the way, what happens after the thread “wakes up”? Will it immediately continue its execution from where it left off? No. After the thread wakes up—when the time passed as an argument to expires Thread.sleep()—it enters the runnable state . However, this does not mean that the thread scheduler will run it. It is quite possible that it will give preference to some other “non-sleeping” thread, and our “freshly awakened” thread will continue working a little later. Be sure to remember: “waking up does not mean continuing to work at that very second!”

Thread.join() method

Multithreading: what the methods of the Thread class do - 4The method join()suspends execution of the current thread until another thread completes. If we have 2 threads, t1and t2, and we write -
t1.join()
t2will not start working until t1 has completed its work. The method join()can be used to ensure the execution sequence of threads. Let's look at the work join()using an example:
public class ThreadExample extends Thread {

   @Override
   public void run() {

       System.out.println("Начало работы потока " + getName());

       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("Поток " + getName() +  " завершил работу.");
   }
}


public class Main {

   public static void main(String[] args) throws InterruptedException {

       ThreadExample t1 = new ThreadExample();
       ThreadExample t2 = new ThreadExample();

       t1.start();


 /*Второй поток t2 начнет выполнение только после того, How будет завершен
       (or бросит исключение) первый поток - t1*/
       try {
           t1.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       t2.start();

       //Главный поток продолжит работу только после того, How t1 и t2 завершат работу
       try {
           t1.join();
           t2.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       System.out.println("Все потоки закончor работу, программа завершена");

   }
}
We have created a simple class ThreadExample. Its task is to display a message on the screen about the start of work, then fall asleep for 5 seconds and at the end inform about the completion of work. Nothing complicated. The main logic is contained in the class Main. Look at the comments: using the method, join()we successfully control the execution sequence of threads. If you remember the beginning of the topic, the thread scheduler did this. He launched them at his own discretion: differently each time. Here, using the method, we ensured that first the thread would be launched and executed t1, then the thread t2, and only after them the main thread of program execution. Go ahead. In real programs, you will often encounter situations when you need to interrupt the execution of some thread. For example, our thread is running, but it is waiting for a certain event or condition to be met. If this happens, it stops. It would probably be logical if there were some method like stop(). However, everything is not so simple. Once upon a time, a method Thread.stop()in Java actually existed and allowed you to interrupt the work of a thread. But later it was removed from the Java library. You can look it up in the Oracle documentation and see that it is marked as deprecated . Why? Because it simply stopped the flow without any additional work. For example, a thread could work with data and change something in it. Then he was abruptly knocked out stop()in the middle of work - and that was it. There was no correct shutdown, no freeing of resources, no even error handling - none of this happened. The method stop(), to exaggerate, simply destroyed everything in its path. Its operation can be compared to how someone pulls the plug from the socket to turn off a computer. Yes, you can achieve the desired result. But everyone understands that in a couple of weeks the computer will not say “thank you” for this. For this reason, the logic for interrupting threads in Java was changed, and now a special method is used - interrupt().

Thread.interrupt() method

What happens if you call a method interrupt() on a thread ? There are 2 options:
  1. If the object was in the waiting state at that moment, for example, joinor sleep, the waiting will be interrupted and the program will throw InterruptedException.
  2. If the thread was in a working state at that moment, the object’s boolean flag will be set interrupted.
But we will have to check the object for the value of this flag and complete the work correctly ourselves! For this purpose, the class Threadhas a special method - boolean isInterrupted(). Let's go back to the clock example from the main course lecture. For convenience, it is slightly simplified:
public class Clock extends Thread {

   public static void main(String[] args) throws InterruptedException {
       Clock clock = new Clock();
       clock.start();

       Thread.sleep(10000);
       clock.interrupt();
   }

   public void run() {
       Thread current = Thread.currentThread();

       while (!current.isInterrupted())
       {
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               System.out.println("Работа потока была прервана");
               break;
           }
           System.out.println("Tik");
       }
   }
}
In our case, the clock starts and starts ticking every second. At the 10th second we interrupt the clock flow. As you already know, if the thread we are trying to interrupt is in one of the wait states, this results in InterruptedException. This type of exception is a checked exception, so it can be easily caught and our program termination logic executed. That's what we did. Here is our result: Tik Tik Tik Tik Tik Tik Tik Tik Tik The thread's work was interrupted. This concludes our introduction to the main methods of the class Thread. To consolidate your knowledge, you can watch this video lecture about multithreading:
it will serve as excellent additional material! At the end, after an overview of the methods, it tells exactly what we will go through next in the course :) Good luck!
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION