JavaRush /Java Blog /Random EN /Multithreading: what the methods of the Thread class do

Multithreading: what the methods of the Thread class 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 several of its methods work. Previously, when we studied class methods, most often we simply wrote it like this: “method name” -> “what it does”.
Multithreading: what the methods of the Thread class do - 1
It doesn't work that way with Thread methods :) Their logic is more complicated, and it's hard to figure it out without a few examples.

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 run(). But he, of course, will not start on his own. To do this, we call the method on our object start(). Multithreading: what the methods of the Thread class do - 2Let's recall an 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();
       }
   }
}
Note that to start a thread, you need to call a special methodstart(), not a methodrun()! This mistake is easy to make, especially at the beginning of multithreading. If in our example you call the method on the 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 started and executed is determined by the superintelligence inside our operating system - the thread scheduler. Maybe just lucky? Of course, it's not about luck. You can verify this by running the program a couple more times. The fact is that a direct method callrun()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 executed.main(). 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 fulfilled run(), call it start(). Let's go further.

Thread.sleep() Method

To suspend 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 it is necessary to "put" the stream 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 Note that the method sleep()is static: it puts the current thread to sleep. That is the one that is currently working. Another important nuance: the flow in the sleep state can be interrupted. In this case, an exception will be thrown 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 - ends Thread.sleep()- it goes into the runnable state, "workable". However, this does not mean that the thread scheduler will launch it. It is quite possible that it will give preference to some other “non-sleeping” thread, and our “freshly awakened” one will continue working a little later. Be sure to remember: “waking up does not mean continuing to work at the same second”!

Thread.join() method

Multithreading: what the methods of the Thread class do - 4The method join()suspends the execution of the current thread until another thread completes. If we have 2 threads, t1and t2, and we will write −
t1.join()
t2won't start until t1 has finished its own. The method join()can be used to guarantee the sequence of execution of threads. Let's see how it works join()with 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 report the completion of work. Nothing complicated. The main logic is in the Main. Look at the comments: with the help of the method, join()we successfully control the sequence of execution of threads. If you remember the beginning of the topic, the thread scheduler was doing this. He launched them at his own discretion: each time in a different way. Here, using the method, we guaranteed that the thread will be launched and executed first t1, then -t2, and only after them - the main thread of program execution. Go ahead. In real programs, you will often encounter situations when it will be necessary to interrupt the execution of a thread. For example, our thread is running, but it is waiting for a certain event or condition. If this happens, it stops. It would probably be logical if there were some method of type stop(). However, everything is not so simple. Once upon a time, the method Thread.stop()in Java really was and allowed to interrupt the work of the thread. But later it was removed from the Java library. You can look it up in the Oracle documentation and see that it's marked as deprecated. Why? Because it just stopped the thread without doing any extra work. For example, a thread could work with data and change something in them. Then he was sharply cut down by the method stop()in the middle of work - and that's it. No graceful shutdown, no release of resources, or at least error handling - none of this happened. The method stop(), to exaggerate, simply crushed everything in its path. His work can be compared to how someone pulls the plug out of the socket to turn off the computer. Yes, you can get 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 has been changed, and now a special method is used - interrupt().

Thread.interrupt() method

What happens if a method interrupt() is called 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 out InterruptedException.
  2. If the thread was in a healthy state at that moment, the boolean flag will be set on the object interrupted.
But we will have to check the object for the value of this flag and correctly complete the work ourselves! To do this, 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 flow of the clock. As you already know, if the thread we are trying to interrupt is in one of the wait states, this will result in InterruptedException. This kind of exception is checked, so it can be easily caught and executed by our program termination logic. Which is what we did. Here is our result: Tik Tik Tik Tik Tik Tik Tik Tik Tik The thread was interrupted This concludes our introduction to the main methods of the Thread. To consolidate knowledge, you can watch this video lecture on multithreading:
it will serve as an excellent supplementary material! At the end, after a review of the methods, it tells exactly what we will be going through further in the course :) Good luck!
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION