Java Threads


Java Threads

Threads allow the system to run smoothly by doing multiple things at once.

Threads can be used to perform complex tasks in the background without disrupting the main system.


Creating a Thread

There are two ways to make a thread.

It can be created by extending the Thread class and exceeding its run() method:


Extend Syntax
public class Main extends Thread {
            public void run() {
              System.out.println("This code is running in a thread");
            }
          }

Another way to make a thread is to use the Runnable interface:


Implement Syntax
public class Main implements Runnable {
            public void run() {
              System.out.println("This code is running in a thread");
            }
          }


Running Threads

If the class extends the Thread class, the string can be run by creating a class pattern and dialing the start() path:


Extend Syntax
public class Main extends Thread {
            public static void main(String[] args) {
              Main thread = new Main();
              thread.start();
              System.out.println("This code is outside of the thread");
            }
            public void run() {
              System.out.println("This code is running in a thread");
            }
          }

If the class is using the Runnable interface, the thread can be run by forwarding the class instance to the Thread object builder and calling the start() method of the series:


Implement Syntax
public class Main implements Runnable {
            public static void main(String[] args) {
              Main obj = new Main();
              Thread thread = new Thread(obj);
              thread.start();
              System.out.println("This code is outside of the thread");
            }
            public void run() {
              System.out.println("This code is running in a thread");
            }
          }

The difference between the "extending" and "implementing" cables.

The main difference is that if the class extends the Thread class, you cannot expand any other category, but by using the active interface, it is possible to expand from another class as well, such as: MyClass class extends OtherClass Runnable resources.


Concurrency Problems

Because the threads work simultaneously with other parts of the program, there is no way to know which program will work with the program. When the cables and the main program read and write the same variables, the values ​​do not predict. The problems that result from this are called concurrency problems.


Example

A code example where the value of the variable amount is unpredictable:

public class Main extends Thread {
            public static int amount = 0;
          
            public static void main(String[] args) {
              Main thread = new Main();
              thread.start();
              System.out.println(amount);
              amount++;
              System.out.println(amount);
            }
          
            public void run() {
              amount++;
            }
          }

To avoid concurrency problems, it is best to share as many features between the threads as possible. If the attributes need to be shared, the only solution that can be used is to use the isAlive() series method to check that the series is complete before using any attributes that can be changed by the series.


Example

Use isAlive() to prevent concurrency problems:

public class Main extends Thread {
            public static int amount = 0;
          
            public static void main(String[] args) {
              Main thread = new Main();
              thread.start();
              // Wait for the thread to finish
              while(thread.isAlive()) {
              System.out.println("Waiting...");
            }
            // Update amount and print its value
            System.out.println("Main: " + amount);
            amount++;
            System.out.println("Main: " + amount);
            }
            public void run() {
              amount++;
            }
          }