Per-thread context

Let's assume that we have the following Order class:

public class Order {

private final int customerId;

public Order(int customerId) {
this.customerId = customerId;
}

// getter and toString() omitted for brevity
}

And, we write CustomerOrder as follows:

public class CustomerOrder implements Runnable {

private static final Logger logger
= Logger.getLogger(CustomerOrder.class.getName());
private static final Random rnd = new Random();

private static final ThreadLocal<Order>
customerOrder = new ThreadLocal<>();

private final int customerId;

public CustomerOrder(int customerId) {
this.customerId = customerId;
}

@Override
public void run() {
logger.info(() -> "Given customer id: " + customerId
+ " | " + customerOrder.get()
+ " | " + Thread.currentThread().getName());

customerOrder.set(new Order(customerId));

try {
Thread.sleep(rnd.nextInt(2000));
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
logger.severe(() -> "Exception: " + ex);
}

logger.info(() -> "Given customer id: " + customerId
+ " | " + customerOrder.get()
+ " | " + Thread.currentThread().getName());

customerOrder.remove();
}
}

For each customerId, we have a dedicated thread that we control:

CustomerOrder co1 = new CustomerOrder(1);
CustomerOrder co2 = new CustomerOrder(2);
CustomerOrder co3 = new CustomerOrder(3);

new Thread(co1).start();
new Thread(co2).start();
new Thread(co3).start();

So, each thread modifies a certain instance of CustomerOrder (there is a particular thread for each instance).

The run() method fetches the order for the given customerId and stores it in the ThreadLocal variable, using the set() method.

A possible output will be as follows:

[14:48:20] [INFO] 
Given customer id: 3 | null | Thread-2
[14:48:20] [INFO]
Given customer id: 2 | null | Thread-1
[14:48:20] [INFO]
Given customer id: 1 | null | Thread-0

[14:48:20] [INFO]
Given customer id: 2 | Order{customerId=2} | Thread-1
[14:48:21] [INFO]
Given customer id: 3 | Order{customerId=3} | Thread-2
[14:48:21] [INFO]
Given customer id: 1 | Order{customerId=1} | Thread-0

In scenarios like the preceding one, avoid using ExecutorService. There is no guarantee that each Runnable (of a given customerId) will be handled by the same thread at every execution. This may lead to weird results.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.41.205