Allow to get details of the Thread that powers a SingleThreadEventExecutor.
Motivation: for debugging and metrics reasons its sometimes useful to be able to get details of the the Thread that powers a SingleThreadEventExecutor. Modifications: - Expose ThreadProperties - Add unit test. Result: It's now possible to get details of the Thread that powers a SingleThreadEventExecutor.
This commit is contained in:
parent
01c29e5cc7
commit
63014fe118
@ -19,6 +19,7 @@ import io.netty.util.internal.PlatformDependent;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import java.lang.Thread.State;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@ -68,6 +69,7 @@ public abstract class SingleThreadEventExecutor extends AbstractScheduledEventEx
|
||||
private final EventExecutorGroup parent;
|
||||
private final Queue<Runnable> taskQueue;
|
||||
private final Thread thread;
|
||||
private final ThreadProperties threadProperties;
|
||||
private final Semaphore threadLock = new Semaphore(0);
|
||||
private final Set<Runnable> shutdownHooks = new LinkedHashSet<Runnable>();
|
||||
private final boolean addTaskWakesUp;
|
||||
@ -152,7 +154,7 @@ public abstract class SingleThreadEventExecutor extends AbstractScheduledEventEx
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
threadProperties = new DefaultThreadProperties(thread);
|
||||
taskQueue = newTaskQueue();
|
||||
}
|
||||
|
||||
@ -697,6 +699,13 @@ public abstract class SingleThreadEventExecutor extends AbstractScheduledEventEx
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ThreadProperties} of the {@link Thread} that powers the {@link SingleThreadEventExecutor}.
|
||||
*/
|
||||
public final ThreadProperties threadProperties() {
|
||||
return threadProperties;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected boolean wakesUpForTask(Runnable task) {
|
||||
return true;
|
||||
@ -717,4 +726,52 @@ public abstract class SingleThreadEventExecutor extends AbstractScheduledEventEx
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DefaultThreadProperties implements ThreadProperties {
|
||||
private final Thread t;
|
||||
|
||||
DefaultThreadProperties(Thread t) {
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State state() {
|
||||
return t.getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return t.getPriority();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterrupted() {
|
||||
return t.isInterrupted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDaemon() {
|
||||
return t.isDaemon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return t.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long id() {
|
||||
return t.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackTraceElement[] stackTrace() {
|
||||
return t.getStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAlive() {
|
||||
return t.isAlive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2015 The Netty Project
|
||||
*
|
||||
* The Netty Project 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 io.netty.util.concurrent;
|
||||
|
||||
/**
|
||||
* Expose details for a {@link Thread}.
|
||||
*/
|
||||
public interface ThreadProperties {
|
||||
/**
|
||||
* @see {@link Thread#getState()}.
|
||||
*/
|
||||
Thread.State state();
|
||||
|
||||
/**
|
||||
* @see {@link Thread#getPriority()}.
|
||||
*/
|
||||
int priority();
|
||||
|
||||
/**
|
||||
* @see {@link Thread#isInterrupted()}.
|
||||
*/
|
||||
boolean isInterrupted();
|
||||
|
||||
/**
|
||||
* @see {@link Thread#isDaemon()} ()}.
|
||||
*/
|
||||
boolean isDaemon();
|
||||
|
||||
/**
|
||||
* @see {@link Thread#getName()} ()}.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* @see {@link Thread#getId()}.
|
||||
*/
|
||||
long id();
|
||||
|
||||
/**
|
||||
* @see {@link Thread#getStackTrace()}.
|
||||
*/
|
||||
StackTraceElement[] stackTrace();
|
||||
|
||||
/**
|
||||
* @see {@link Thread#isAlive()}.
|
||||
*/
|
||||
boolean isAlive();
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2015 The Netty Project
|
||||
*
|
||||
* The Netty Project 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 io.netty.util.concurrent;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class SingleThreadEventExecutorTest {
|
||||
|
||||
@Test
|
||||
public void testThreadDetails() {
|
||||
final AtomicReference<Thread> threadRef = new AtomicReference<Thread>();
|
||||
SingleThreadEventExecutor executor = new SingleThreadEventExecutor(
|
||||
null, new DefaultThreadFactory("test"), false) {
|
||||
@Override
|
||||
protected void run() {
|
||||
threadRef.set(Thread.currentThread());
|
||||
while (!confirmShutdown()) {
|
||||
Runnable task = takeTask();
|
||||
if (task != null) {
|
||||
task.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
executor.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// NOOP
|
||||
}
|
||||
}).syncUninterruptibly();
|
||||
ThreadProperties threadProperties = executor.threadProperties();
|
||||
Assert.assertSame(threadProperties, executor.threadProperties());
|
||||
|
||||
Thread thread = threadRef.get();
|
||||
Assert.assertEquals(thread.getId(), threadProperties.id());
|
||||
Assert.assertEquals(thread.getName(), threadProperties.name());
|
||||
Assert.assertEquals(thread.getPriority(), threadProperties.priority());
|
||||
Assert.assertEquals(thread.getState(), threadProperties.state());
|
||||
Assert.assertEquals(thread.isAlive(), threadProperties.isAlive());
|
||||
Assert.assertEquals(thread.isDaemon(), threadProperties.isDaemon());
|
||||
Assert.assertEquals(thread.isInterrupted(), threadProperties.isInterrupted());
|
||||
Assert.assertTrue(threadProperties.stackTrace().length > 0);
|
||||
executor.shutdownGracefully();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user