public class Foo{// SimpleDateFormat is not thread-safe, so give one to each threadprivate static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){@Overrideprotected SimpleDateFormat initialValue(){return new SimpleDateFormat("yyyyMMdd HHmm");}};
public String formatIt(Date date){return formatter.get().format(date);}}
// This class will provide a thread local variable which// will provide a unique ID for each threadclass ThreadId {// Atomic integer containing the next thread ID to be assignedprivate static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's IDprivate static final ThreadLocal<Integer> threadId =ThreadLocal.<Integer>withInitial(()-> {return nextId.getAndIncrement();});
// Returns the current thread's unique ID, assigning it if necessarypublic static int get() {return threadId.get();}}
public class ThreadLocalDemo1 implements Runnable {// threadlocal variable is createdprivate static final ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>(){@Overrideprotected SimpleDateFormat initialValue(){System.out.println("Initializing SimpleDateFormat for - " + Thread.currentThread().getName() );return new SimpleDateFormat("dd/MM/yyyy");}};
public static void main(String[] args) {ThreadLocalDemo1 td = new ThreadLocalDemo1();// Two threads are createdThread t1 = new Thread(td, "Thread-1");Thread t2 = new Thread(td, "Thread-2");t1.start();t2.start();}
@Overridepublic void run() {System.out.println("Thread run execution started for " + Thread.currentThread().getName());System.out.println("Date formatter pattern is " + dateFormat.get().toPattern());System.out.println("Formatted date is " + dateFormat.get().format(new Date()));}
}
Key = One ThreadLocal object shared across threads.value = Mutable object which has to be used synchronously, this will be instantiated for each thread.
class SimpleDateFormatInstancePerThread {
private static final ThreadLocal<SimpleDateFormat> dateFormatHolder = new ThreadLocal<SimpleDateFormat>() {
@Overrideprotected SimpleDateFormat initialValue() {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd") {UUID id = UUID.randomUUID();@Overridepublic String toString() {return id.toString();};};System.out.println("Creating SimpleDateFormat instance " + dateFormat +" for Thread : " + Thread.currentThread().getName());return dateFormat;}};
/** Every time there is a call for DateFormat, ThreadLocal will return calling* Thread's copy of SimpleDateFormat*/public static DateFormat getDateFormatter() {return dateFormatHolder.get();}
public static void cleanup() {dateFormatHolder.remove();}}
import java.util.concurrent.atomic.AtomicInteger;import java.util.stream.IntStream;
public class ThreadId {private static final AtomicInteger nextId = new AtomicInteger(1000);
// Thread local variable containing each thread's IDprivate static final ThreadLocal<Integer> threadId = ThreadLocal.withInitial(() -> nextId.getAndIncrement());
// Returns the current thread's unique ID, assigning it if necessarypublic static int get() {return threadId.get();}
public static void main(String[] args) {
new Thread(() -> IntStream.range(1, 3).forEach(i -> {System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());})).start();
new Thread(() -> IntStream.range(1, 3).forEach(i -> {System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());})).start();
new Thread(() -> IntStream.range(1, 3).forEach(i -> {System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());})).start();
}}
public class Book implements Runnable {private static final ThreadLocal<List<String>> WORDS = ThreadLocal.withInitial(ArrayList::new);
private final String bookName; // It is also the thread's nameprivate final List<String> words;
public Book(String bookName, List<String> words) {this.bookName = bookName;this.words = Collections.unmodifiableList(words);}
public void run() {WORDS.get().addAll(words);System.out.printf("Result %s: '%s'.%n", bookName, String.join(", ", WORDS.get()));}
public static void main(String[] args) {Thread t1 = new Thread(new Book("BookA", Arrays.asList("wordA1", "wordA2", "wordA3")));Thread t2 = new Thread(new Book("BookB", Arrays.asList("wordB1", "wordB2")));t1.start();t2.start();}}