Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

Java ThreadLocal – thread data separation

farenda 2016-11-26 0

One way to prevent concurrent modifications from different Threads is to given them their own local data. Java ThreadLocal allows to do thread data separation.

ThreadLocal holder

Let’s write a simple class that will hold ThreadLocal variable for each thread. We’ll use ThreadLocal.withInitial(Supplier<? extends T>) static factory method to create an instance of ThreadLocal with initialValue throwing exception, because in our case having customer is required:

package com.farenda.java.lang;

import java.util.function.Supplier;

public class CurrentCustomer {

    // No customer is logical error, so we prevent that:
    private static final Supplier<String> STATE_CHECKER = () -> {
        throw new IllegalStateException("Customer must be set!");
    };

    private static final ThreadLocal<String> customer
            = ThreadLocal.withInitial(STATE_CHECKER);

    public static String get() {
        return customer.get();
    }

    public static void set(String id) {
        customer.set(id);
    }
}

Note that access to customer ThreadLocal through get() and set(String id) methods is not synchronized. ThreadLocal takes care of that.

Example Java Application

To test the above code we’ll use ExecutorService to start a few worker threads each of which will process own customer.

Worker accessing ThreadLocal

Simple Worker thread that stores current customer in ThreadLocal variable, does processing (calling a number of layers below that access the same ThreadLocal variable) and shows current customer id at the end:

package com.farenda.java.lang;

import java.util.concurrent.TimeUnit;

public class Worker implements Runnable {

    private final String customer;

    public Worker(String customer) {
        this.customer = customer;
    }

    @Override
    public void run() {
        // Each worker sets own customer:
        CurrentCustomer.set(customer);
        System.out.printf("Thread %s, customer: %s%n",
                Thread.currentThread().getName(),
                CurrentCustomer.get());
        sleep();
        System.out.printf("%s processed customer: %s%n",
                Thread.currentThread().getName(),
                CurrentCustomer.get());
    }

    private void sleep() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            // ignore
        }
    }
}

Executing worker threads

package com.farenda.java.lang;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadLocalExample {

    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new Worker("AAA"));
        executor.execute(new Worker("BBB"));
        executor.execute(new Worker("CCC"));
        executor.shutdown();
    }
}

The output clearly shows that each Worker is accessing the same customer id at the beginning and at the end of execution:

Thread pool-1-thread-3, customer: CCC
Thread pool-1-thread-1, customer: AAA
Thread pool-1-thread-2, customer: BBB
pool-1-thread-1 processed customer: AAA
pool-1-thread-3 processed customer: CCC
pool-1-thread-2 processed customer: BBB

References:

  • Java Concurrency Tutorial
Share with the World!
Categories Java Tags java, java-concurrency, java8
Previous: Clojure REPL docs
Next: Java 8 remove selected item from Collection

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2022

sponsored