From a5879bf8b7342e81c87b7fa084fb05713dd27b66 Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Fri, 14 Apr 2017 04:16:53 +0200 Subject: [PATCH] Bael 822 thread local (#1625) * code for thread local article * userNameSecret * better to string * fix typo --- .../com/baeldung/threadlocal/Context.java | 17 +++++++++ .../threadlocal/SharedMapWithUserContext.java | 21 +++++++++++ .../ThreadLocalWithUserContext.java | 20 +++++++++++ .../baeldung/threadlocal/UserRepository.java | 10 ++++++ .../baeldung/threadlocal/ThreadLocalTest.java | 35 +++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/threadlocal/Context.java create mode 100644 core-java/src/main/java/com/baeldung/threadlocal/SharedMapWithUserContext.java create mode 100644 core-java/src/main/java/com/baeldung/threadlocal/ThreadLocalWithUserContext.java create mode 100644 core-java/src/main/java/com/baeldung/threadlocal/UserRepository.java create mode 100644 core-java/src/test/java/com/baeldung/threadlocal/ThreadLocalTest.java diff --git a/core-java/src/main/java/com/baeldung/threadlocal/Context.java b/core-java/src/main/java/com/baeldung/threadlocal/Context.java new file mode 100644 index 0000000000..241fb2f1e0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/threadlocal/Context.java @@ -0,0 +1,17 @@ +package com.baeldung.threadlocal; + + +public class Context { + private final String userName; + + public Context(String userName) { + this.userName = userName; + } + + @Override + public String toString() { + return "Context{" + + "userNameSecret='" + userName + '\'' + + '}'; + } +} diff --git a/core-java/src/main/java/com/baeldung/threadlocal/SharedMapWithUserContext.java b/core-java/src/main/java/com/baeldung/threadlocal/SharedMapWithUserContext.java new file mode 100644 index 0000000000..e5854e218a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/threadlocal/SharedMapWithUserContext.java @@ -0,0 +1,21 @@ +package com.baeldung.threadlocal; + + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class SharedMapWithUserContext implements Runnable { + public final static Map userContextPerUserId = new ConcurrentHashMap<>(); + private final Integer userId; + private UserRepository userRepository = new UserRepository(); + + public SharedMapWithUserContext(Integer userId) { + this.userId = userId; + } + + @Override + public void run() { + String userName = userRepository.getUserNameForUserId(userId); + userContextPerUserId.put(userId, new Context(userName)); + } +} diff --git a/core-java/src/main/java/com/baeldung/threadlocal/ThreadLocalWithUserContext.java b/core-java/src/main/java/com/baeldung/threadlocal/ThreadLocalWithUserContext.java new file mode 100644 index 0000000000..0d6a7e5572 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/threadlocal/ThreadLocalWithUserContext.java @@ -0,0 +1,20 @@ +package com.baeldung.threadlocal; + + +public class ThreadLocalWithUserContext implements Runnable { + private static final ThreadLocal userContext = new ThreadLocal<>(); + private final Integer userId; + private UserRepository userRepository = new UserRepository(); + + public ThreadLocalWithUserContext(Integer userId) { + this.userId = userId; + } + + + @Override + public void run() { + String userName = userRepository.getUserNameForUserId(userId); + userContext.set(new Context(userName)); + System.out.println("thread context for given userId: " + userId + " is: " + userContext.get()); + } +} diff --git a/core-java/src/main/java/com/baeldung/threadlocal/UserRepository.java b/core-java/src/main/java/com/baeldung/threadlocal/UserRepository.java new file mode 100644 index 0000000000..3fe76f75c0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/threadlocal/UserRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.threadlocal; + +import java.util.UUID; + + +public class UserRepository { + public String getUserNameForUserId(Integer userId) { + return UUID.randomUUID().toString(); + } +} diff --git a/core-java/src/test/java/com/baeldung/threadlocal/ThreadLocalTest.java b/core-java/src/test/java/com/baeldung/threadlocal/ThreadLocalTest.java new file mode 100644 index 0000000000..ac2e8fbe63 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/threadlocal/ThreadLocalTest.java @@ -0,0 +1,35 @@ +package com.baeldung.threadlocal; + + +import org.junit.Test; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; + +public class ThreadLocalTest { + @Test + public void givenThreadThatStoresContextInAMap_whenStartThread_thenShouldSetContextForBothUsers() throws ExecutionException, InterruptedException { + //when + SharedMapWithUserContext firstUser = new SharedMapWithUserContext(1); + SharedMapWithUserContext secondUser = new SharedMapWithUserContext(2); + new Thread(firstUser).start(); + new Thread(secondUser).start(); + + Thread.sleep(3000); + //then + assertEquals(SharedMapWithUserContext.userContextPerUserId.size(), 2); + } + + @Test + public void givenThreadThatStoresContextInThreadLocal_whenStartThread_thenShouldStoreContextInThreadLocal() throws ExecutionException, InterruptedException { + //when + ThreadLocalWithUserContext firstUser = new ThreadLocalWithUserContext(1); + ThreadLocalWithUserContext secondUser = new ThreadLocalWithUserContext(2); + new Thread(firstUser).start(); + new Thread(secondUser).start(); + + Thread.sleep(3000); + } + +}