Java 为什么';在线程中嵌入Runnable是不可能的吗?
据我从文档以及stackoverflow上发布的其他问题(如“”和“”)中了解,无法获取嵌入Java 为什么';在线程中嵌入Runnable是不可能的吗?,java,multithreading,concurrency,runnable,Java,Multithreading,Concurrency,Runnable,据我从文档以及stackoverflow上发布的其他问题(如“”和“”)中了解,无法获取嵌入线程中的可运行对象的引用 具有这种可能性的一个场景是在实现一个方法时,该方法的签名无法修改,因为我们正在重写另一个类或接口中定义的方法,并且需要根据当前线程中嵌入的可运行的类型执行不同的操作 例如,如果我们在Thread类中有一个名为getRunnable的方法,我们可以这样做: if (Thread.currentThread().getRunnable() instanceof Type1) {
线程中的可运行对象的引用
具有这种可能性的一个场景是在实现一个方法时,该方法的签名无法修改,因为我们正在重写另一个类或接口中定义的方法,并且需要根据当前线程中嵌入的可运行的类型执行不同的操作
例如,如果我们在Thread
类中有一个名为getRunnable
的方法,我们可以这样做:
if (Thread.currentThread().getRunnable() instanceof Type1) {
// do something...
} else {
// do something else...
}
当我们希望确保方法中包含的操作仅由某些线程而不是其他线程执行时,这也很有用
所以我想知道,Java开发人员决定不允许从线程
获取可运行的
实例有什么具体原因,或者这是值得通知的缺失特性吗?如果您认为该选择背后没有理由,但不值得将其作为缺少的功能通知它,那么在上述场景中您会使用什么策略
所以我想知道,Java开发人员决定不允许从线程获取可运行实例有什么具体原因吗
这可能不是一个要求。Runnable
本身应该能够识别自己的类,因此它需要获取该信息的想法是奇怪的。它还可以起到保护作用,使其他线程无法访问正在另一个线程中运行的类
如果您需要从应用程序的其他部分访问当前的Runnable
,那么我建议使用ThreadLocal
。在run()
方法中,您可以设置它,然后在其他类中检索它。但是,您需要将ThreadLocal
放在全局可访问的位置
您还可以处理当前堆栈跟踪以找出封闭的Runnable
类,这更像是一种黑客行为,但它会起作用。有几种方法可以解决此问题:
保持Runnable
s到执行它们的线程的映射(使用Map
或ThreadLocal
)
使用反射从线程访问可运行的:
private static final Field target;
static {
Field f = null;
try {
f = Thread.class.getDeclaredField("target");
f.setAccessible(true);
} catch (NoSuchFieldException e) {
// might happen in a different version of Java (works in Java 7)
e.printStackTrace();
}
target = f;
}
public static Runnable getTarget(Thread t) {
try {
return (Runnable) target.get(t);
} catch (IllegalAccessException e) {
// shouldn't happen, we already made the field accessible when we created it
e.printStackTrace();
}
return null;
}
有一个间接的方法可能会有帮助,你可以得到堆栈跟踪
StackTraceElement[] stackTraceElement = thread.getStackTrace();
for(StackTraceElement e :stackTraceElement){
System.out.println("Trace "+e.getClassName());
}
输出:
跟踪java.lang.Thread
跟踪com.emc.multi-threading.RunnableDemo
Trace java.lang.Thread使用main
方法,主线程的“可运行”是什么?像您在示例中所做的那样,在instanceof
的结果上进行分支几乎从来都不是一个好主意。我不打算提供这个答案,因为这会非常密集,但是嘿。您可以研究如何使用线程堆栈跟踪Thread.currentThread().getStackTrace()
。我不知道原因,但是您也可以扩展Thread类,在子类中保留对Runnable对象的引用,并提供getter方法在需要时获取Runnable。不是所有Thread
实例都有Runnable,不是吗?