# 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)

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