java 获取调用者方法_Java如何从单独的线程获取调用者?

本文探讨了如何在Java中有效地追踪调用者信息,尤其是在多线程环境下进行大量日志记录时如何避免阻塞UI线程的方法。通过自定义线程和使用Logger的特性,可以在不影响性能的情况下获取调用者信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嗯……不确定这是否可行,但如果你在一个单独的线程上运行,怎么会在Java中抓取真正的调用者的类名(理想情况下也是方法名)?我想将类名称卸载到一个单独的线程(以便在我每秒执行100次日志记录操作时不阻止UI线程).

例如:

class Main {

public void callerMethod() {

Thread.currentThread().getStackTrace()[2].getMethodName(); // This gets me the caller. However, this is expensive to do on the UI Thread 100+ times per second. a call here can take up 70ms

new Thread(new Runnable() {

@Override

public void run() {

new SecondObject().iWantToKnowMyCaller();

}

}).start();

}

}

class SecondObject {

public void iWantToKnowMyCaller() {

// how do i get the caller method here so that it's "callerMethod" from "Main" ?

}

}

用例是这样的:我正在记录大量数据,我根本不想阻止主线程.一些日志记录可能是快速和小数据,但有些可能会记录转储很多东西.问题还在于,现在,编写代码的方式,大约有600个入口点进入callerMethod(),因此重构将是一个相当大的挑战.

或者:

如果你能证明Thread.currentThread().getStackTrace()[2] .getMethodName();保证是每次少于5毫秒的恒定时间操作,那么在主线程上可以接受.

解决方法:

编辑:

好的,您想要避免堆栈跟踪.我环顾了一下:确定调用者的复杂性实际上是在LogRecord中.如果您可以通过Logger.setSourceClassName()手动设置调用者(根本不需要任何字符串),那么LogRecord将不再构建堆栈跟踪来查找调用者的名称.

public class ThreadTest

{

public static void main( String[] args )

{

LogRecord lr = new LogRecord( Level.INFO, "Hi" );

lr.setSourceClassName( "ThreadTest.main" ); // anything, including null

Logger.getAnonymousLogger().log( lr );

}

}

原始答案:

子类化线程将起作用,但我有点质疑你为什么要这样做.对于调试可能,但这是我能想到的唯一用例. (P.S.我必须在堆栈跟踪中更改您的偏移量.“2”将获得callerMethod的调用者 – 在下面的示例中为“main”.)

public class ThreadTest

{

public static void main( String[] args )

{

new Main().callerMethod();

}

}

class Main {

public void callerMethod() {

final String callee = Thread.currentThread().getStackTrace()[1].getMethodName(); // This gets me the caller

new MyThread(new Runnable() {

@Override

public void run() {

new SecondObject().iWantToKnowMyCaller();

}

}){

@Override

public String getInvoker() { return callee; }}.start();

}

}

abstract class MyThread extends Thread implements Invoker {

public MyThread( Runnable r )

{

super( r );

}

}

class SecondObject {

public void iWantToKnowMyCaller() {

// how do i get the caller method here so that it's "callerMethod" from "Main" ?

System.out.println( ((MyThread)(Thread.currentThread())).getInvoker() );

}

}

interface Invoker {

String getInvoker();

}

标签:java,multithreading

来源: https://codeday.me/bug/20190624/1277390.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值