/hazelcast/src/main/java/com/hazelcast/impl/ThreadContext.java

https://bitbucket.org/gabral6_gmailcom/hazelcast · Java · 257 lines · 191 code · 46 blank · 20 comment · 24 complexity · 8252dfec3a9e6b1d72068c1f4c5b0911 MD5 · raw file

  1. /*
  2. * Copyright (c) 2008-2013, Hazelcast, Inc. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.hazelcast.impl;
  17. import com.hazelcast.core.ManagedContext;
  18. import com.hazelcast.impl.ConcurrentMapManager.MEvict;
  19. import com.hazelcast.logging.ILogger;
  20. import com.hazelcast.logging.Logger;
  21. import com.hazelcast.nio.Data;
  22. import com.hazelcast.nio.Serializer;
  23. import java.util.HashMap;
  24. import java.util.Iterator;
  25. import java.util.Map;
  26. import java.util.concurrent.ConcurrentHashMap;
  27. import java.util.concurrent.ConcurrentMap;
  28. import java.util.concurrent.atomic.AtomicInteger;
  29. import java.util.logging.Level;
  30. public final class ThreadContext {
  31. private final static AtomicInteger newThreadId = new AtomicInteger();
  32. private static final ConcurrentMap<Thread, ThreadContext> mapContexts = new ConcurrentHashMap<Thread, ThreadContext>(1000);
  33. private final Thread thread;
  34. private final Serializer serializer = new Serializer();
  35. private final Map<FactoryImpl, HazelcastInstanceThreadContext> mapHazelcastInstanceContexts = new HashMap<FactoryImpl, HazelcastInstanceThreadContext>(2);
  36. private volatile FactoryImpl currentFactory = null;
  37. private ThreadContext(Thread thread) {
  38. this.thread = thread;
  39. }
  40. public static ThreadContext get() {
  41. Thread currentThread = Thread.currentThread();
  42. ThreadContext threadContext = mapContexts.get(currentThread);
  43. if (threadContext == null) {
  44. try {
  45. threadContext = new ThreadContext(Thread.currentThread());
  46. mapContexts.put(currentThread, threadContext);
  47. Iterator<Thread> threads = mapContexts.keySet().iterator();
  48. while (threads.hasNext()) {
  49. Thread thread = threads.next();
  50. if (!thread.isAlive()) {
  51. threads.remove();
  52. }
  53. }
  54. } catch (OutOfMemoryError e) {
  55. OutOfMemoryErrorDispatcher.onOutOfMemory(e);
  56. throw e;
  57. }
  58. if (mapContexts.size() > 1000) {
  59. String msg = " ThreadContext is created!! You might have too many threads. Is that normal?";
  60. Logger.getLogger(ThreadContext.class.getName()).log(Level.WARNING, mapContexts.size() + msg);
  61. }
  62. }
  63. return threadContext;
  64. }
  65. public static void shutdownAll() {
  66. mapContexts.clear();
  67. }
  68. public static synchronized void shutdown(Thread thread) {
  69. ThreadContext threadContext = mapContexts.remove(thread);
  70. if (threadContext != null) {
  71. threadContext.shutdown();
  72. }
  73. }
  74. public void shutdown() {
  75. currentFactory = null;
  76. mapHazelcastInstanceContexts.clear();
  77. }
  78. public void shutdown(FactoryImpl factory) {
  79. mapHazelcastInstanceContexts.remove(factory);
  80. }
  81. public void finalizeTxn() {
  82. getCallContext().finalizeTransaction();
  83. }
  84. public TransactionImpl getTransaction() {
  85. return getCallContext().getTransaction();
  86. }
  87. public long getTxnId() {
  88. return getCallContext().getTxnId();
  89. }
  90. public FactoryImpl getCurrentFactory() {
  91. return currentFactory;
  92. }
  93. public ManagedContext getCurrentManagedContext() {
  94. return currentFactory != null ? currentFactory.managedContext : null;
  95. }
  96. public void setCurrentFactory(FactoryImpl currentFactory) {
  97. this.currentFactory = currentFactory;
  98. }
  99. public void reset() {
  100. finalizeTxn();
  101. }
  102. public byte[] toByteArray(Object obj) {
  103. return serializer.toByteArray(obj);
  104. }
  105. public Data toData(Object obj) {
  106. return serializer.writeObject(obj);
  107. }
  108. public Object toObject(Data data) {
  109. return serializer.readObject(data);
  110. }
  111. public HazelcastInstanceThreadContext getHazelcastInstanceThreadContext(FactoryImpl factory) {
  112. if (factory == null) {
  113. ILogger logger = Logger.getLogger(ThreadContext.class.getName());
  114. logger.log(Level.SEVERE, "Factory is null", new Throwable());
  115. }
  116. HazelcastInstanceThreadContext hic = mapHazelcastInstanceContexts.get(factory);
  117. if (hic != null) return hic;
  118. hic = new HazelcastInstanceThreadContext(factory);
  119. mapHazelcastInstanceContexts.put(factory, hic);
  120. return hic;
  121. }
  122. public CallCache getCallCache(FactoryImpl factory) {
  123. return getHazelcastInstanceThreadContext(factory).getCallCache();
  124. }
  125. /**
  126. * Is this thread remote Java or CSharp Client thread?
  127. *
  128. * @return true if the thread is for Java or CSharp Client, false otherwise
  129. */
  130. public boolean isClient() {
  131. return getCallContext().isClient();
  132. }
  133. public int createNewThreadId() {
  134. return newThreadId.incrementAndGet();
  135. }
  136. public CallContext getCallContext() {
  137. return getHazelcastInstanceThreadContext(currentFactory).getCallContext();
  138. }
  139. class HazelcastInstanceThreadContext {
  140. FactoryImpl factory;
  141. CallCache callCache;
  142. volatile CallContext callContext = null;
  143. HazelcastInstanceThreadContext(FactoryImpl factory) {
  144. this.factory = factory;
  145. callContext = (new CallContext(createNewThreadId(), false));
  146. }
  147. public CallCache getCallCache() {
  148. if (callCache == null) {
  149. callCache = new CallCache(factory);
  150. }
  151. return callCache;
  152. }
  153. public CallContext getCallContext() {
  154. return callContext;
  155. }
  156. public void setCallContext(CallContext callContext) {
  157. this.callContext = callContext;
  158. }
  159. }
  160. class CallCache {
  161. final FactoryImpl factory;
  162. final ConcurrentMapManager.MPut mput;
  163. final ConcurrentMapManager.MGet mget;
  164. final ConcurrentMapManager.MRemove mremove;
  165. final ConcurrentMapManager.MEvict mevict;
  166. CallCache(FactoryImpl factory) {
  167. this.factory = factory;
  168. mput = factory.node.concurrentMapManager.new MPut();
  169. mget = factory.node.concurrentMapManager.new MGet();
  170. mremove = factory.node.concurrentMapManager.new MRemove();
  171. mevict = factory.node.concurrentMapManager.new MEvict();
  172. }
  173. public ConcurrentMapManager.MPut getMPut() {
  174. mput.reset();
  175. mput.request.lastTime = System.nanoTime();
  176. return mput;
  177. }
  178. public ConcurrentMapManager.MGet getMGet() {
  179. mget.reset();
  180. mget.request.lastTime = System.nanoTime();
  181. return mget;
  182. }
  183. public ConcurrentMapManager.MRemove getMRemove() {
  184. mremove.reset();
  185. mremove.request.lastTime = System.nanoTime();
  186. return mremove;
  187. }
  188. public MEvict getMEvict() {
  189. mevict.reset();
  190. return mevict;
  191. }
  192. }
  193. public int getThreadId() {
  194. return getCallContext().getThreadId();
  195. }
  196. public void setCallContext(CallContext callContext) {
  197. getHazelcastInstanceThreadContext(currentFactory).setCallContext(callContext);
  198. }
  199. @Override
  200. public boolean equals(Object o) {
  201. if (this == o) return true;
  202. if (o == null || getClass() != o.getClass()) return false;
  203. ThreadContext that = (ThreadContext) o;
  204. if (thread != null ? !thread.equals(that.thread) : that.thread != null) return false;
  205. return true;
  206. }
  207. @Override
  208. public int hashCode() {
  209. return thread != null ? thread.hashCode() : 0;
  210. }
  211. }