Zoeken…


Opmerkingen

Het best te gebruiken voor objecten die afhankelijk zijn van internals tijdens het aanroepen van een aanroep, maar anders SimpleDateFormat zijn, zoals SimpleDateFormat , Marshaller

Overweeg het gebruik van ThreadLocalRandom voor Random gebruik van ThreadLocalRandom

ThreadLocal Java 8 functionele initialisatie

public static class ThreadLocalExample
{
    private static final ThreadLocal<SimpleDateFormat> format = 
        ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd_HHmm"));

    public String formatDate(Date date)
    {
        return format.get().format(date);
    }
}

Basisthread Lokaal gebruik

Java ThreadLocal wordt gebruikt om lokale ThreadLocal te maken. Het is bekend dat threads van een object zijn variabelen delen, dus de variabele is niet thread-safe. We kunnen synchronisatie gebruiken voor threadveiligheid, maar als we synchronisatie willen vermijden, stelt ThreadLocal ons in staat om variabelen te creëren die lokaal zijn voor de thread, dat wil zeggen dat alleen die thread die variabelen kan lezen of schrijven, dus de andere threads die hetzelfde stuk code uitvoeren hebben geen toegang tot elkaar ThreadLocal-variabelen.

Dit kan worden gebruiktwe kunnen ThreadLocal variabelen gebruiken. in situaties waarin u een threadpool heeft, bijvoorbeeld in een webservice. Het maken van een SimpleDateFormat object bijvoorbeeld elke keer voor elk verzoek is tijdrovend en een statisch object kan niet worden gemaakt omdat SimpleDateFormat niet thread-safe is, dus we kunnen een ThreadLocal maken zodat we thread-veilige bewerkingen kunnen uitvoeren zonder de overhead van het maken van SimpleDateFormat elke tijd.

Het onderstaande stukje code laat zien hoe het kan worden gebruikt:

Elke thread heeft zijn eigen ThreadLocal variabele en ze kunnen de methoden get() en set() gebruiken om de standaardwaarde op te halen of de waarde lokaal te wijzigen in Thread.

ThreadLocal instanties zijn doorgaans statische privévelden in klassen die de status aan een thread willen koppelen.

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

package com.examples.threads;

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

public class ThreadLocalExample implements Runnable{

    // SimpleDateFormat is not thread-safe, so give one to each thread
 // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @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();
        }
        
        formatter.set(new SimpleDateFormat());
        
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
    }

}

Output:

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 we aan de uitvoer kunnen zien, heeft Thread-0 de waarde van formatter gewijzigd, maar is de standaardformatter van thread-2 nog steeds hetzelfde als de geïnitialiseerde waarde.

Meerdere threads met één gedeeld object

In dit voorbeeld hebben we maar één object, maar het wordt gedeeld tussen / uitgevoerd op verschillende threads. Gewoon gebruik van velden om de status op te slaan zou niet mogelijk zijn omdat de andere thread dat ook zou zien (of waarschijnlijk niet ziet).

public class Test {
    public static void main(String[] args) {
        Foo foo = new Foo();
        new Thread(foo, "Thread 1").start();
        new Thread(foo, "Thread 2").start();
    }
}

In Foo tellen we vanaf nul. In plaats van de status in een veld op te slaan, slaan we ons huidige nummer op in het ThreadLocal-object dat statisch toegankelijk is. Merk op dat de synchronisatie in dit voorbeeld niet gerelateerd is aan het gebruik van ThreadLocal, maar eerder zorgt voor een betere console-uitvoer.

public class Foo implements Runnable {
    private static final int ITERATIONS = 10;
    private static final ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    @Override
    public void run() {
        for (int i = 0; i < ITERATIONS; i++) {
            synchronized (threadLocal) {
                //Although accessing a static field, we get our own (previously saved) value.
                int value = threadLocal.get();
                System.out.println(Thread.currentThread().getName() + ": " + value);
                
                //Update our own variable
                threadLocal.set(value + 1);

                try {
                    threadLocal.notifyAll();
                    if (i < ITERATIONS - 1) {
                        threadLocal.wait();
                    }
                } catch (InterruptedException ex) {
                }
            }
        }
    }
}

Uit de uitvoer kunnen we zien dat elke thread voor zichzelf telt en niet de waarde van de andere gebruikt:

Thread 1: 0
Thread 2: 0
Thread 1: 1
Thread 2: 1
Thread 1: 2
Thread 2: 2
Thread 1: 3
Thread 2: 3
Thread 1: 4
Thread 2: 4
Thread 1: 5
Thread 2: 5
Thread 1: 6
Thread 2: 6
Thread 1: 7
Thread 2: 7
Thread 1: 8
Thread 2: 8
Thread 1: 9
Thread 2: 9


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow