---
# System prepended metadata

title: Threads intro

---

# Threads intro

###### tags: java, concurrency 


## Creating Threads

Below are few ways to create threads

**Case 1:** Extending `Thread` Class and overriding run method 

```java 
public class FirstThread extends Thread {  
  @Override  
  public void run() {  
        System.out.println("Heellooo!");  
  }  
}  
  
// Creating Thread  
Thread thread = new FirstThread();

```

**Case 2:** Implementing the Runnable Interface 

```java 
Thread newThread = new Thread(new Runnable() {  
  @Override  
  public void run() {  
        System.out.println("Hello from the thread!");  
  }  
});

```

> Since, `Runnable` interface is a functional interface. this can be simplified via lambda expressions 

```java 
 
Thread newThread = new Thread(() -> System.out.println("Hello from the thread!"));

```

**Note:** creating threads via `Runnable` interface is preferred  
* in Java each class can extend only one class. When you extend the Thread class, after that you can’t extend any other class if you require. 
* Additionally, extends in Java is used to add/modify some functionality from a subclass. In this case, we do not add/modify anything to Thread class


## Creating Threads in ExecutorService 

`ExecutorService` is an interface that we do not have to implement on our own, the Java provides us with ready-made implementations. Thanks to that we can easily create a thread or a pool of threads, which will work according to our expectations. The most important methods that this interface provides are:

* `submit(Runnable task)` - allows you to send ‘task’ (implementation of the Runnable interface) to be executed (**note:** we have no guarantee that it will be started immediately! It depends on the current status of ExecutorService, task queue, available threads, etc).
* `shutdown()` - allows you to finish threads correctly, previously completing all tasks and releasing all resources. Calling this method is required before the application is finished!


## Synchronization in Java 

### Race Condition

consider the below program 

```java 
class Counter {  
    private int value;  
  
 public void increment() {  
        value++;  
  }  
  
    public int getValue() {  
        return value;  
  }  
}  
  
public class RaceCondition {  
    public static void main(String[] args) throws InterruptedException {  
        Counter counter = new Counter();  
  Runnable r = () -> {  
            for (int i = 0; i < 50000; i++) {  
                counter.increment();  
  }  
        };  
  
  Thread t1 = new Thread(r);  
  Thread t2 = new Thread(r);  
  Thread t3 = new Thread(r);  
  
  t1.start();  
  t2.start();  
  t3.start();  
  
  t1.join();  
  t2.join();  
  t3.join();  
  
  System.out.println(counter.getValue());  
  }  
}

```

> `Thread.join()` ensures that the current main thread waits till this thread has finished it's execution 

we normally expect the `counter` value to show `1,50,000` but in reality that won't happen, because each thread is updating the shared resource `int counter` concurrently. 

we can avoid this by making the `increment()` method  by adding the `synchronized`  keyword, this will make sure that only one thread at any point of time has access to this `increment()` method. 

```java 
public synchronized void increment() {
    value ++; //static method - the whole class is used as a monitor
}
```

```java 
 public void increment() {  
        synchronized (this) {  
            value++;  // standard method - a class(this) instance is used as a monitor
  }  
    }  

```

we can avoid the race condition by changing our code as shown above. 

### Java Volatile keyword 

volatile modifier ensures that every thread reading a given attribute will see the latest saved value of that attribute.

> Volatile --> Guarantees visibility and NOT atomicity
Synchronization (Locking) --> Guarantees visibility and atomicity (if done properly) 

![](https://i.imgur.com/8tQHtr0.png)

volatile keyword ensures that value is not cached at CPU cache  and directly read from main memory for each thread. 
