Curriculum
Course: Java Basic
Login

Curriculum

Java Basic

Java Home

0/1

Java Introduction

0/1

Java Get Started

0/1

Java Syntax

0/1

Java Comments

0/1

Java Type Casting

0/1

Java Operators

0/1

Java Booleans

0/1

Java Switch

0/1

Java Break / Continue

0/1

Java Errors and Exception

0/1
Text lesson

Java Threads

Java Threads

Threads enable a program to operate more efficiently by executing multiple tasks concurrently.

They can handle complex operations in the background without disrupting the main program.

Creating a Thread

Two methods exist for creating a thread.

One approach involves extending the Thread class and overriding its run() method.

Extend Syntax

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

An alternative method to create a thread is by implementing 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 a class extends the Thread class, the thread can be executed by creating an instance of the class and invoking its start() method.

Extend Example

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");
  }
}

When a class implements the Runnable interface, the thread can be executed by passing an instance of the class to a Thread object’s constructor, followed by calling the start() method of the thread.

Implement Example

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");
  }
}

 

Distinguish between “extending” and “implementing” Threads.

The primary distinction is that when a class extends the Thread class, it precludes extending any other class. Conversely, by implementing the Runnable interface, it remains feasible to extend from another class, such as: class MyClass extends OtherClass implements Runnable.

Concurrency Problems

Since threads execute concurrently with other parts of the program, the order in which the code runs is unpredictable. When both threads and the main program access and modify the same variables, the resulting values become unpredictable. These issues stemming from concurrent access are referred to as concurrency problems.

Example

An example code where the value of the variable “amount” becomes 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 mitigate concurrency issues, it’s advisable to minimize the sharing of attributes between threads. If attributes must be shared, one potential solution is to utilize the isAlive() method of the thread to verify whether the thread has completed its execution before accessing any attributes that the thread might alter.

Example

Leverage the isAlive() method to mitigate concurrency issues.

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++;
  }
}