Skip to content

Instantly share code, notes, and snippets.

@mgandin
Last active February 23, 2022 01:03
Show Gist options
  • Save mgandin/7150858 to your computer and use it in GitHub Desktop.
Save mgandin/7150858 to your computer and use it in GitHub Desktop.
A small example to monitor Java Thread Pool with JMX
package fr.mga.concurrent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class ConcurrentFooBarQix implements Callable<String> {
private int toFooBar;
public ConcurrentFooBarQix(int toFooBar) {
this.toFooBar = toFooBar;
}
@Override
public String call() throws Exception {
return fooBarQix(toFooBar);
}
public String fooBarQix(int anInteger) {
String result = "";
if (anInteger % 3 == 0)
result += "FOO";
if (anInteger % 5 == 0)
result += "BAR";
if (anInteger % 7 == 0)
result += "QIX";
String integer = String.valueOf(anInteger);
for (int i = 0; i < integer.length(); i++) {
if (integer.charAt(i) == '3')
result += "FOO";
if (integer.charAt(i) == '5')
result += "BAR";
if (integer.charAt(i) == '7')
result += "QIX";
}
return result.equals("") ? integer : result;
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext(
"spring.xml");
List<Callable<String>> callables = new ArrayList<Callable<String>>();
for (int i = 1; i <= 100; i++) {
ConcurrentFooBarQix concurrentFooBarQix = new ConcurrentFooBarQix(i);
callables.add(concurrentFooBarQix);
}
ExecutorService executorService = (ExecutorService) context
.getBean("executorService");
List<Future<String>> futures = executorService.invokeAll(callables);
for (Future<String> future : futures) {
System.out.println(future.get());
}
try {
Thread.sleep(1000 * 60 * 5);
} catch (final Throwable t) {
}
executorService.shutdown();
}
}
package fr.mga.concurrent;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mga.concurrent.ConcurrentFooBarQix;
public class ConcurrentFooBarQixTest {
private ConcurrentFooBarQix concurrentFooBarQix;
@Before
public void setUp() {
concurrentFooBarQix = new ConcurrentFooBarQix(0);
}
@Test
public void shoud_return_number() {
Assert.assertEquals("1", concurrentFooBarQix.fooBarQix(1));
}
@Test public void should_return_foo() {
Assert.assertEquals("FOOFOO",concurrentFooBarQix.fooBarQix(3));
Assert.assertEquals("FOO",concurrentFooBarQix.fooBarQix(6));
Assert.assertEquals("FOO",concurrentFooBarQix.fooBarQix((13)));
}
@Test public void should_return_bar() {
Assert.assertEquals("BARBAR",concurrentFooBarQix.fooBarQix(5));
Assert.assertEquals("BAR",concurrentFooBarQix.fooBarQix(10));
Assert.assertEquals("BAR",concurrentFooBarQix.fooBarQix(52));
}
@Test public void should_return_qix() {
Assert.assertEquals("QIXQIX",concurrentFooBarQix.fooBarQix(7));
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="threadPoolMBean" class="fr.mga.concurrent.ThreadPoolMBean" >
<constructor-arg type="java.util.concurrent.ThreadPoolExecutor" ref="executorService"/>
</bean>
<bean id="executorService" class="org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="keepAliveSeconds" value="5" />
</bean>
<!-- you may just copy the following lines -->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="autodetect" value="true" />
<property name="namingStrategy" ref="namingStrategy" />
<property name="assembler" ref="assembler" />
</bean>
<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
</beans>
package fr.mga.concurrent;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
@ManagedResource
public class ThreadPoolMBean {
private ThreadPoolExecutor executorService;
public ThreadPoolMBean(ThreadPoolExecutor service) {
executorService = service;
}
@ManagedAttribute(description = "Returns the number of threads that execute tasks")
public int getActiveCount() {
return executorService.getActiveCount();
}
@ManagedAttribute(description = "Returns the total number of completed tasks")
public long getCompletedTaskCount() {
return executorService.getCompletedTaskCount();
}
@ManagedAttribute(description = "Returns the size of the core pool of threads")
public int getCorePoolSize() {
return executorService.getCorePoolSize();
}
@ManagedAttribute(description = "Returns the largest number of threads that have been in the pool")
public int getLargestPoolSize() {
return executorService.getLargestPoolSize();
}
@ManagedAttribute(description = "Returns the max size allowed in the pool of threads")
public int getMaximumPoolSize() {
return executorService.getMaximumPoolSize();
}
@ManagedAttribute(description = "Returns the number of additional elements that this queue can "
+ "accept without "
+ "blocking")
public int getQueueRemainingCapacity() {
return executorService.getQueue().remainingCapacity();
}
@ManagedAttribute(description = "Returns the total number of tasks that have ever been scheduled for execution ")
public long getTaskCount() {
return executorService.getTaskCount();
}
@ManagedAttribute(description = "Sets the core size of the pool")
public void setCorePoolSize(int corePoolSize) {
executorService.setCorePoolSize(corePoolSize);
}
@ManagedAttribute(description = "Sets the max size allowed in the pool of threads")
public void setMaximumPoolSize(int maximumPoolSize) {
executorService.setMaximumPoolSize(maximumPoolSize);
}
}
@yrsf
Copy link

yrsf commented Oct 14, 2016

This helped. Thanks

@kswat
Copy link

kswat commented Nov 8, 2020

Hi, I see ManagedResource with getters, but How to use these? OK used jmc!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment