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