JavaRush /Java Blog /Random EN /Coffee break #160. Deep dive into Java ThreadLocal. Scann...

Coffee break #160. Deep dive into Java ThreadLocal. Scanner class in Java

Published in the Random EN group

Deep Dive into Java ThreadLocal

Source: Devgenios Today you will learn about ThreadLocal, one of the common classes used in developing Java applications. Coffee break #160.  Deep dive into Java ThreadLocal.  Scanner class in Java - 1

What is ThreadLocal?

The ThreadLocal class stores local variables for threads. These variables are isolated between different threads and can only be accessed by their own thread. Use cases for ThreadLocal :
  1. Isolate data between threads.
  2. Session management for database connections.
  3. Storing thread transaction information.

How to use ThreadLocal?

Let's look at a simple example.
public static void main(String[] args) {
    //Создаем ThreadLocal
    ThreadLocal<String> local = new ThreadLocal<>();
    //Создаем новый класс Random
    Random random = new Random();
    //Создаем 5 потоков
    IntStream.range(0, 5).forEach(a-> new Thread(()-> {
        //Присваиваем meaning каждому потоку
        local.set(a+"  "+random.nextInt(100));
        System.out.println("Thread number and its local value  "+ local.get());
    }).start());
}
In the above code, we create a ThreadLocal class , create 5 threads, assign a value to ThreadLocal in each thread and print. When outputting we get: Coffee break #160.  Deep dive into Java ThreadLocal.  Scanner class in Java - 2

What's under the hood?

If you look closely, you can see that there are two important methods in ThreadLocal from this code example.
  • public T get() {}

  • public void set (T value) {}

Let's look at the setter method in the ThreadLocal source code :
public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
}
The setter method first gets the current thread and calls the getMap() method to get the ThreadLocalMap class . If map exists, take the current stream t as the key, the input parameter as the value, and set the {key:value} pair to map. If not, then create a map . Now you may have a question - what is ThreadLocalMap ?
static class ThreadLocalMap {
   /**
    * The entries in this hash map extend WeakReference, using
    * its main ref field as the key (which is always a
    * ThreadLocal object).  Note that null keys (i.e. entry.get()
    * == null) mean that the key is no longer referenced, so the
    * entry can be expunged from table.  Such entries are referred to
    * as "stale entries" in the code that follows.
    */
    static class Entry extends WeakReference<ThreadLocal<?>> {
       /** The value associated with this ThreadLocal. */
       Object value;
       Entry(ThreadLocal<?> k, Object v) {
           super(k);
           value = v;
       }
    }
}
ThreadLocalMap is an internal static class in ThreadLocal that defines an Entry class to store data. Entry uses the ThreadLocal instance as the key and sets the value that we pass. If this sounds too confusing at this point, just remember that it is the Entry class in ThreadLocalMap that does the actual storing of the values. To get data from ThreadLocal we use the getter method :
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
}
In the getter method , we will use currentThread as the key to get the ThreadLocalMap . Then map will getEntry() based on the ThreadLocal instance and return the Entry instance and then the stored value. Here's a diagram to help you figure it out: Coffee break #160.  Deep dive into Java ThreadLocal.  Scanner class in Java - 3Coffee break #160.  Deep dive into Java ThreadLocal.  Scanner class in Java - 4
  1. Each thread maintains a reference to a ThreadLocalMap .

  2. ThreadLocalMap is an inner static class of ThreadLocal and uses the Entry class for storage.

  3. A ThreadLocalMap key is an instance of ThreadLocal and can have multiple ThreadLocals .

  4. ThreadLocal itself does not store a value, but it is a key for the thread that will help get the value from ThreadLocalMap .

Note that it is better to remove ThreadLocal to avoid OOM (Out-of-Memory Error) due to a “weak” reference in the Entry class .

Scanner class in Java

Source: Medium This post will help you become familiar with the Scanner class in Java. Coffee break #160.  Deep dive into Java ThreadLocal.  Scanner class in Java - 5The Scanner class in Java is a class that we use when we want to get a value from the user. The easiest way to understand it is with examples, so let's look at it more clearly. Creating a Scanner class is one of three steps we take to get a value from the user. The first step is to create an object from the scanner class.
Scanner scan=new Scanner(System.in);
Now we have a scanner object. This object will have the Scanner properties from the Scanner class . After the first step, the user can already enter the desired value, but if we do not guide the user and display the value in the console or in the application, it will not be very good in terms of usability. Therefore, it is better to inform and guide the user:
System.out.println("Please enter your name");
String name=scan.next();
System.out.println("Your Name:"+name);
In the first line we ask the user what we want from him. This actually has nothing to do with the scanner, but it's always good to give hints to your users. In the second line we will assign the value that the user enters into the data and save it so we can use it later. In the last line we see that we can use the value received from the user at our discretion. Let's add a few more details to our code:
System.out.println("Please enter your last name");

String lastName=scan.next();

System.out.println("Your Name " + name + " " + "Your Last Name" + lastName);
Basically, we repeated the previous two lines, asked the user for the value and saved it. Now in the last line we used two values ​​that we took from the user and which are now used together.
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION