All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hippo4j.springboot.starter.core.BaseThreadDetailStateHandler Maven / Gradle / Ivy

There is a newer version: 1.5.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.hippo4j.springboot.starter.core;

import cn.hippo4j.common.api.ThreadDetailState;
import cn.hippo4j.common.model.ThreadDetailStateInfo;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.ReflectUtil;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.core.executor.DynamicThreadPoolWrapper;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Base thread detail state handler.
 *
 * 

The Java 8 implementation is temporarily provided, * {@link ThreadDetailState} interface can be customized. * * @author chen.ma * @date 2022/1/9 13:01 */ @Slf4j public class BaseThreadDetailStateHandler implements ThreadDetailState { private final String WORKERS = "workers"; private final String THREAD = "thread"; @Override public List getThreadDetailStateInfo(String threadPoolId) { DynamicThreadPoolWrapper poolWrapper = GlobalThreadPoolManage.getExecutorService(threadPoolId); ThreadPoolExecutor executor = poolWrapper.getExecutor(); return getThreadDetailStateInfo(executor); } @Override public List getThreadDetailStateInfo(ThreadPoolExecutor threadPoolExecutor) { List resultThreadState = new ArrayList(); try { // TODO: Should the object be copied deeply to avoid the destruction of the worker HashSet workers = (HashSet) ReflectUtil.getFieldValue(threadPoolExecutor, WORKERS); if (CollectionUtil.isEmpty(workers)) { return resultThreadState; } for (Object worker : workers) { Thread thread; try { thread = (Thread) ReflectUtil.getFieldValue(worker, THREAD); if (thread == null) { log.warn("Reflection get worker thread is null. Worker :: {}", worker); continue; } } catch (Exception ex) { log.error("Reflection get worker thread exception. Worker :: {}", worker, ex); continue; } long threadId = thread.getId(); String threadName = thread.getName(); String threadStatus = thread.getState().name(); StackTraceElement[] stackTrace = thread.getStackTrace(); List stacks = new ArrayList(stackTrace.length); for (int i = 0; i < stackTrace.length; i++) { stacks.add(stackTrace[i].toString()); } ThreadDetailStateInfo threadState = new ThreadDetailStateInfo(); threadState.setThreadId(threadId) .setThreadName(threadName) .setThreadStatus(threadStatus) .setThreadStack(stacks); resultThreadState.add(threadState); } } catch (Exception ex) { log.error("Failed to get thread status.", ex); } return resultThreadState; } }