SpringContextBootstrappingInitializer
which is defined in cache.xml
's initializer to call ThreadPoolTaskExecutor
/ThreadPoolTaskScheduler
bean to run tasks like loading data from external Database into VMware GemFire when cacheserver is starting.ThreadPoolTaskExecutor
/ThreadPoolTaskScheduler
will remain in the Cacheserver jvm process even VMware GemFire related threads are closed completely when Gemfire Cacheserver is shutting down.
Cache.xml
<initializer> <class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name> <parameter name="contextConfigLocations"> <string> classpath:config/customer-gemfire-dbaccess.xml, classpath:config/customer-gemfire-server-beans.xml </string> </parameter> </initializer>
ThreadPoolTaskExecutor
bean sample setting:<bean id="ThreadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="8"></property> <property name="keepAliveSeconds" value="3000" /> <property name="maxPoolSize" value="10" /> <property name="queueCapacity" value="10000" /> </bean>
ThreadPoolTaskScheduler
bean sample setting: <bean id="scheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"> <property name="poolSize" value="100"/> </bean>
"scheduler-97" prio=10 tid=0x0000000001ceb000 nid=0x2bf5 waiting on condition [0x00007f36efd2f000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000079279a8f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1085) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) "ThreadPoolTaskExecutor-3" prio=10 tid=0x00007f36f9093800 nid=0x75d8 waiting on condition [0x00007f36f1c70000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007927b2240> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745)
<property name="daemon" value="true"/>
property to the ThreadPoolTaskScheduler
ThreadPoolTaskExecutorbean
so that the created threads are all daemon thread and Cacheserver process will exit gracefully without any zombie non-daemon threads.
<bean id="scheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="poolSize" value="100"/>
<property name="daemon" value="true"/>
</bean>