mirror of
https://gitee.com/arthas/arthas.git
synced 2024-11-29 18:58:37 +08:00
vmtool command support interrupt thread. #2427
This commit is contained in:
parent
929adc8c9d
commit
735ec2e0b5
@ -1,5 +1,7 @@
|
||||
package arthas;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ZhangZiCheng 2021-02-12
|
||||
* @author hengyunabc 2021-04-26
|
||||
@ -70,6 +72,17 @@ public class VmTool implements VmToolMXBean {
|
||||
forceGc0();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interruptSpecialThread(int threadId) {
|
||||
Map<Thread, StackTraceElement[]> allThread = Thread.getAllStackTraces();
|
||||
for (Map.Entry<Thread, StackTraceElement[]> entry : allThread.entrySet()) {
|
||||
if (entry.getKey().getId() == threadId) {
|
||||
entry.getKey().interrupt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] getInstances(Class<T> klass) {
|
||||
return getInstances0(klass, -1);
|
||||
|
@ -20,6 +20,13 @@ public interface VmToolMXBean {
|
||||
*/
|
||||
public void forceGc();
|
||||
|
||||
/**
|
||||
* 打断指定线程
|
||||
*
|
||||
* @param threadId 线程ID
|
||||
*/
|
||||
void interruptSpecialThread(int threadId);
|
||||
|
||||
public <T> T[] getInstances(Class<T> klass);
|
||||
|
||||
/**
|
||||
|
@ -3,9 +3,11 @@ package arthas;
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.taobao.arthas.common.VmToolUtils;
|
||||
@ -182,4 +184,30 @@ public class VmToolTest {
|
||||
|
||||
Assertions.assertThat(interfaceInstances[0]).isEqualTo(ObjectInstances[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_interrupt_thread() throws InterruptedException {
|
||||
String threadName = "interruptMe";
|
||||
final RuntimeException[] re = new RuntimeException[1];
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
System.out.printf("Thread name is: [%s], thread id is: [%d].\n", Thread.currentThread().getName(),Thread.currentThread().getId());
|
||||
TimeUnit.SECONDS.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
re[0] = new RuntimeException("interrupted " + Thread.currentThread().getId() + " thread success.");
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread interruptMe = new Thread(runnable,threadName);
|
||||
Thread interruptMe1 = new Thread(runnable,threadName);
|
||||
|
||||
interruptMe.start();
|
||||
interruptMe1.start();
|
||||
|
||||
VmTool tool = initVmTool();
|
||||
tool.interruptSpecialThread((int) interruptMe.getId());
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
Assert.assertEquals(("interrupted " + interruptMe.getId() + " thread success."), re[0].getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ import arthas.VmTool;
|
||||
+ " vmtool --action getInstances --className java.lang.String --limit 10\n"
|
||||
+ " vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext\n"
|
||||
+ " vmtool --action forceGc\n"
|
||||
+ " vmtool --action interruptThread -t 1\n"
|
||||
+ Constants.WIKI + Constants.WIKI_HOME + "vmtool")
|
||||
//@formatter:on
|
||||
public class VmToolCommand extends AnnotatedCommand {
|
||||
@ -63,7 +64,7 @@ public class VmToolCommand extends AnnotatedCommand {
|
||||
private VmToolAction action;
|
||||
private String className;
|
||||
private String express;
|
||||
|
||||
private int threadId;
|
||||
private String hashCode = null;
|
||||
private String classLoaderClass;
|
||||
/**
|
||||
@ -149,8 +150,14 @@ public class VmToolCommand extends AnnotatedCommand {
|
||||
this.express = express;
|
||||
}
|
||||
|
||||
@Option(shortName = "t", longName = "threadId", required = false)
|
||||
@Description("The id of the thread to be interrupted")
|
||||
public void setThreadId(int threadId) {
|
||||
this.threadId = threadId;
|
||||
}
|
||||
|
||||
public enum VmToolAction {
|
||||
getInstances, forceGc
|
||||
getInstances, forceGc, interruptThread
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -225,6 +232,12 @@ public class VmToolCommand extends AnnotatedCommand {
|
||||
vmToolInstance().forceGc();
|
||||
process.write("\n");
|
||||
process.end();
|
||||
return;
|
||||
} else if (VmToolAction.interruptThread.equals(action)) {
|
||||
vmToolInstance().interruptSpecialThread(threadId);
|
||||
process.write("\n");
|
||||
process.end();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user