Voorbeeld van Java ThreadLocal

Java ThreadLocal wordt gebruikt om thread-local variabelen te creëren. We weten dat alle threads van een object dezelfde variabelen delen, waardoor de variabele niet thread-safe is. We kunnen synchronisatie gebruiken voor threadveiligheid, maar als we synchronisatie willen vermijden, kunnen we ThreadLocal-variabelen gebruiken.

Java ThreadLocal

Elke thread heeft zijn eigen ThreadLocal-variabele en ze kunnen de get()- en set()-methoden gebruiken om de standaardwaarde te verkrijgen of de waarde lokaal voor de thread te wijzigen. ThreadLocal-instanties zijn meestal private static-velden in klassen die staat willen associëren met een thread.

Java ThreadLocal Voorbeeld

Hier is een klein voorbeeld dat het gebruik van ThreadLocal in een Java-programma laat zien en aantoont dat elke thread zijn eigen kopie heeft van de ThreadLocal-variabele. ThreadLocalExample.java

package com.journaldev.threads;

import java.text.SimpleDateFormat;
import java.util.Random;

public class ThreadLocalExample implements Runnable{

    // SimpleDateFormat is niet thread-safe, dus geef er een aan elke thread
    private static final ThreadLocal formatter = new ThreadLocal(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };
    
    public static void main(String[] args) throws InterruptedException {
        ThreadLocalExample obj = new ThreadLocalExample();
        for(int i=0 ; i<10; i++){
            Thread t = new Thread(obj, ""+i);
            Thread.sleep(new Random().nextInt(1000));
            t.start();
        }
    }

    @Override
    public void run() {
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern());
        try {
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // formatterpatroon wordt hier door de thread gewijzigd, maar dit zal niet worden weerspiegeld naar andere threads
        formatter.set(new SimpleDateFormat());
        
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
    }

}

De uitvoer van het bovenstaande Java ThreadLocal-voorbeeldprogramma is:

Thread Name= 0 default Formatter = yyyyMMdd HHmm
Thread Name= 1 default Formatter = yyyyMMdd HHmm
Thread Name= 0 formatter = M/d/yy h:mm a
Thread Name= 2 default Formatter = yyyyMMdd HHmm
Thread Name= 1 formatter = M/d/yy h:mm a
Thread Name= 3 default Formatter = yyyyMMdd HHmm
Thread Name= 4 default Formatter = yyyyMMdd HHmm
Thread Name= 4 formatter = M/d/yy h:mm a
Thread Name= 5 default Formatter = yyyyMMdd HHmm
Thread Name= 2 formatter = M/d/yy h:mm a
Thread Name= 3 formatter = M/d/yy h:mm a
Thread Name= 6 default Formatter = yyyyMMdd HHmm
Thread Name= 5 formatter = M/d/yy h:mm a
Thread Name= 6 formatter = M/d/yy h:mm a
Thread Name= 7 default Formatter = yyyyMMdd HHmm
Thread Name= 8 default Formatter = yyyyMMdd HHmm
Thread Name= 8 formatter = M/d/yy h:mm a
Thread Name= 7 formatter = M/d/yy h:mm a
Thread Name= 9 default Formatter = yyyyMMdd HHmm
Thread Name= 9 formatter = M/d/yy h:mm a

Zoals je kunt zien aan de output, heeft Thread-0 de waarde van de formatter gewijzigd, maar nog steeds heeft thread-2 de standaardformatter hetzelfde als de geïnitialiseerde waarde. Je ziet hetzelfde patroon voor andere threads ook. Update: De ThreadLocal-klasse is uitgebreid in Java 8 met een nieuwe methode withInitial() die de Supplier-functionele interface als argument gebruikt. Hierdoor kunnen we lambda-uitdrukkingen gebruiken om eenvoudig de ThreadLocal-instantie te maken. Bijvoorbeeld, de bovenstaande formatter ThreadLocal-variabele kan in één regel worden gedefinieerd zoals hieronder:

private static final ThreadLocal<SimpleDateFormat> formatter = 
	ThreadLocal.<SimpleDateFormat>withInitial
	(() -> {return new SimpleDateFormat("yyyyMMdd HHmm");});

Als je nieuw bent met Java 8-functies, bekijk dan Java 8 Features en Java 8 Functional Interfaces. Dat is alles voor ThreadLocal in Java-programmering. Referentie: API Doc

Source:
https://www.digitalocean.com/community/tutorials/java-threadlocal-example