Last active
February 23, 2022 01:03
-
-
Save mgandin/7150858 to your computer and use it in GitHub Desktop.
A small example to monitor Java Thread Pool with JMX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
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
This helped. Thanks