如何拦截线程生命周期?

时间:2015-06-05 08:29:07

标签: java multithreading lifecycle

可以在创建线程时记录。我们需要一个自定义<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <section class="container clearfix"> <div class="text-center"> <ul class="solutions-items"> <li data-text="bla_1">1</li> <li data-text="bla_2">2</li> <li data-text="bla_3">3</li> <li data-text="bla_4">4</li> <li data-text="bla_5">5</li> <li data-text="bla_6">6</li> <li data-text="bla_7">7</li> </ul> </div> </section> <section class="container clearfix"> <div class="text-center solutions-text-p"> <p id="show_data"></p> <button class="solutions-learnmore-btn">{% yaml reference %}</button> </div> </section>实现,从中创建所有线程,并从ThreadFactory方法我们可以记录它。但是,如果我们需要记录线程被销毁和删除的时候我们怎么做呢?

newThread

2 个答案:

答案 0 :(得分:5)

由于您已经在实现自己的线程工厂,因此一种方法是将runnable包装到另一个可在作业启动和完成时记录的runnable中。像这样:

 public Thread newThread(Runnable runnable) {
     Runnable wrapper = new Runnable() {

        @Override
        public void run() {
            System.out.println("Starting thread ...");
            try {
                runnable.run();
                System.out.println("Thread done");
            } catch (Throwable t) {
                System.out.println("Thread exited abnormally");
                // Log exception
            }

        }

     };
     Thread thread = new Thread(threadGroup, wrapper, namePrefix + threadNumber.getAndIncrement(), 0);
    // ...
}

这不会记录实际的线程生命周期,但与例如在线程被销毁时信任终结器进行记录相比,它是可靠的。

System.out.println替换为您选择的日志记录调用。

答案 1 :(得分:1)

您可以在Runnable上创建代理并使用代理Runnable创建一个线程,这样您就可以了解运行方法何时开始和结束

public enum RpiThreadFactory {
    INSTANCE;

    private final AtomicInteger poolNumber = new AtomicInteger(1);
    private final Logger logger = Logger.getLogger(this.name());
    private final ThreadGroup threadGroup;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    private RpiThreadFactory() {
        SecurityManager securityManager = System.getSecurityManager();
        threadGroup = (securityManager != null) ? securityManager.getThreadGroup() : Thread.currentThread().getThreadGroup();
        namePrefix = "RpiPool-" + poolNumber.getAndIncrement() + "-Thread-";
    }

    public Thread newThread(Runnable runnable) {
        Runnable proxyRunnable = (Runnable) Proxy.newProxyInstance(runnable.getClass().getClassLoader(), runnable.getClass().getInterfaces(),
            new RunnableProxy(runnable));
        Thread thread = new Thread(threadGroup, proxyRunnable, namePrefix + threadNumber.getAndIncrement(), 0);
        thread.setPriority(Thread.NORM_PRIORITY);
        thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

            public void uncaughtException(Thread thread, Throwable cause) {
            logger.fine(cause.getMessage());
            }
        });

        logger.fine(thread.toString() + " created.");
        return thread;
    }
}

class RunnableProxy implements InvocationHandler {
    private Runnable runnable;

    public RunnableProxy(Runnable runnable) {
        this.runnable = runnable;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Proxied Runnable Started!!");
        Object object = method.invoke(runnable, args);
        System.out.println("Proxied Runnable Done!!");
        return object;
    }
}