Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java Threading Essentials: Novice to Expert

Java Threading Essentials: Novice to Expert

To be a proficient java developer, you must learn Java Thread programming. Thread is the heart of the Java ecosystem. All the server-side programming model heavily depends on the java concurrency model. In this session, I will explain a few essential aspects of the java thread model from the ground up so that a beginner can build up their concurrency knowledge on top it.

The session will include;

- How to create a simple concurrent program
- Identify the benefits of java threadings
- Understanding the bagasse that comes with threads and how to avoid them
- What are the threadsafe classes available in the JDK

A N M Bazlur Rahman

June 09, 2022
Tweet

More Decks by A N M Bazlur Rahman

Other Decks in Technology

Transcript

  1. PLEASE FASTEN YOUR SEAT BELT (WE ARE TAKING OFF) §

    What is a thread? § How to create a simple concurrent program § Identify the benefits of java threading § Understanding the bagasse that comes with threads and how to avoid them § What are the thread safe classes available in the JDK § This is a beginner-friendly workshop 2022-06-09 @bazlur_rahman 3
  2. § From day 0, Java introduced Threads § Threads are

    units of execution in Java. § They are lightweight processes. § They share the memory spaces. 2022-06-09 @bazlur_rahman 5
  3. § If we have more CPU, threads improve performance (if

    the code is structured correctly) § Improved throughput (technically, more threads == more throughput) § Improves responsiveness; the whole program will not block, even though parts are. § Threads run on the same process, so resource sharing is easy (it has side effect as well) § Economy, we can use all CPUs. So no cpu cycles are wasted 2022-06-09 @bazlur_rahman 6
  4. public class Main { public static void main(String[] args) {

    System.out.println("Im running on: " + Thread.currentThread()); } } //Im running on: Thread[main,5,main] 2022-06-09 @bazlur_rahman 7
  5. public class MyThread extends Thread { @Override public void run()

    { System.out.println("A whole new world!"); } } 2022-06-09 @bazlur_rahman 8
  6. var thread = new MyThread(); thread.start(); - The start() method

    does all the necessary initialization, then calls the run() 2022-06-09 @bazlur_rahman 9
  7. public class MyRunnable implements Runnable{ @Override public void run() {

    System.out.println("A whole new world!"); } } MyRunnable myRunnable = new MyRunnable(); var thread = new Thread(myRunnable); thread.start(); 2022-06-09 @bazlur_rahman 10
  8. var thread = new Thread(() -> { System.out.println("A new thread!");

    }); thread.start(); 2022-06-09 @bazlur_rahman 11
  9. public static void main(String[] args) throws IOException { try (var

    server = new ServerSocket(8080)) { while (true) { var socket = server.accept(); handleRequest(socket); } } } private static void handleRequest (Socket socket) throws IOException { //rest of the codes } 2022-06-09 @bazlur_rahman 13
  10. § public static void main(String[] args) throws IOException { try

    (var server = new ServerSocket(8080)) { while (true) { var socket = server.accept(); new Thread(() -> { handleRequest(socket); }); } } } 2022-06-09 @bazlur_rahman 14
  11. var thread = new Thread(() -> { try { TimeUnit.SECONDS.sleep(5);

    } catch (InterruptedException e) { System.err.println("Thread Interrupted deu to " + e.getMessage()); } throw new RuntimeException("Goodbye cruel world!"); }); thread.start(); thread.join(); We won’t see any Stack Trace for an exception here. 2022-06-09 @bazlur_rahman 15
  12. § We don’t! § Thread dies when the work is

    done 2022-06-09 @bazlur_rahman 18
  13. public class Playground { private static boolean running = false;

    public static void main(String[] args) { var t1 = new Thread(() -> { while (!running) { } System.out.println("Thread"); }); var t2 = new Thread(() -> { running = true; System.out.println("I love "); }); t1.start(); t2.start(); } } 2022-06-09 @bazlur_rahman 20
  14. This is called a visibility problem. private volatile static boolean

    running = false; 2022-06-09 @bazlur_rahman 23
  15. § Caches are flushed immediately § Re-read from main memory

    before use § Or written back to main memory 2022-06-09 @bazlur_rahman 24
  16. § Read/Write from the exact memory location § Deposit &

    withdraw from a bank account § Write on a file from two different threads at the same. § If several threads access a memory location simultaneously, inconsistency appears, which is called a race condition. @bazlur_rahman 2022-06-09 25 Image: Head First Java, 3rd Edition
  17. public class BankAccount { private long balance; public BankAccount(long initialBalance)

    { this.balance = initialBalance; } public void deposit(long amount) { this.balance += amount; } public void withdraw(long amount) { this.deposit(-amount); } public long getBalance() { return balance; } } 2022-06-09 @bazlur_rahman 27
  18. § public class BankAccountWithLock { private long balance; private final

    Object lock = new Object(); public void deposit(long amount) { synchronized (lock) { this.balance += amount; } } public void withdraw(long amount) { synchronized (lock) { this.deposit(-amount); } } } 2022-06-09 @bazlur_rahman 29
  19. § public class IntCounter { private int count; public int

    incrementAndGet() { count = count + 1; return count; } public int getCount() { return count; } } 2022-06-09 @bazlur_rahman 31
  20. public class IntCounter { private int count; public synchronized int

    incrementAndGet() { count = count + 1; return count; } public synchronized int getCount() { return count; } } 2022-06-09 @bazlur_rahman 32
  21. final Object lockA = new Object(); final Object lockB =

    new Object(); Thread t1 = new Thread(() -> { synchronized (lockA) { sleep(); synchronized (lockB) { compute(); } } }); Thread t2 = new Thread(() -> { synchronized (lockB) { synchronized (lockA) { compute(); } } }); 2022-06-09 @bazlur_rahman 34
  22. § Avoid nested locking § Lock Ordering § Use Advance

    Locking (we won’t discuss today) Thread t1 = new Thread(() -> { synchronized (lockA) { sleep(); synchronized (lockB) { compute(); } } }); Thread t2 = new Thread(() -> { synchronized (lockA) { synchronized (lockB) { compute(); } } }); 2022-06-09 @bazlur_rahman 35
  23. public final class Person { private final String name; private

    final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } 2022-06-09 @bazlur_rahman 37
  24. § Thread share memory space. That’s called shared mutable state.

    If multiple threads read/write shared data, that’s where we need to focus. § If we don’t need to change data (read-only), use an immutable object § All immutable objects are thread-safe § When we deal with a shared mutable state, we need to use a lock 2022-06-09 @bazlur_rahman 38
  25. public class AtomicCounter { private AtomicInteger counter = new AtomicInteger();

    public int incrementAndGet() { return counter.incrementAndGet(); } public int getCount() { return counter.get(); } } 2022-06-09 @bazlur_rahman 41
  26. ExecutorService threadPool = Executors.newFixedThreadPool(10); try (var server = new ServerSocket(8080))

    { while (true) { var socket = server.accept(); threadPool.submit(() -> { handleRequest(socket); }); } } 2022-06-09 @bazlur_rahman 48
  27. § Runnable: when we don’t need a result § Callable:

    when we need results. 2022-06-09 @bazlur_rahman 50
  28. § Java Concurrency in Practice - B. Goetz et al.

    § Concurrent Programming in Java - D. Lea § Optimizing Java - B. Evans et al. § https://foojay.io/today/author/bazlur-rahman/ § https://jenkov.com/tutorials/java-concurrency/index.html 2022-06-09 @bazlur_rahman 54