我有一个线程工厂,执行程序,线程类和可运行类。
这是线程类:(threadsCount是一个AtomicInteger,用于跟踪创建的线程数)

public void run() {
    try {
        threadsCount.incrementAndGet();
        super.run();
    } finally {
        threadsCount.decrementAndGet();
    }
}


我的可运行类当前未实现,但具有空的run()方法。

当我尝试调用Executor.execute(new RunnableClazz())时,控件进入了该Thread类-run()方法,当遇到super.run()时,它将转到RunnableClazz#run()方法。

所有这些都很好。但是问题是,在RunnableClazz#run()完成之后,控件不会返回到我的Thread类的“ finally”块。

有任何想法吗?我需要在run()方法结束时手动杀死可运行对象吗?

public class ThreadAA extends Thread {

private static final AtomicInteger threadsCount = new AtomicInteger();
private static final AtomicInteger threadsCreated = new AtomicInteger();
public static final String DEFAULT_NAME = "ThreadAA";

public ThreadAA(Runnable r)
    {
        this(r, DEFAULT_NAME);
    }
public ThreadAA(Runnable r, String threadName)
    {
        super(r, threadName + "-" + threadsCreated.incrementAndGet());

        setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
        {
            public void uncaughtException(Thread t, Throwable e)
            {
                logger.error("Uncaught exception in thread " + t.getName(), e);
            }
        });
    }

@Override
public void run()
    {
        boolean debug = false;
        //just for debug purpose
        debug = true;
        if(debug)
        {
            logger.debug("Running thread " + getName());
        }

        try
        {
            threadsCount.incrementAndGet();
            super.run();
        }
        finally
        {
            threadsCount.decrementAndGet();
            if(debug)
            {
                logger.debug("Done running thread " + getName());
            }
        }
    }

 }


我的RunnableClass:

public class RunnableClazz implements Runnable {

@Override
public void run() {
        logger.debug("Inside RunnableClazz");
}

}


调用此可运行对象的方法如下所示:

  Executor executor = new Executor(25, 100, 1L, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(5), new TFactory("abc"));

    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.execute(new RunnableClazz());

executor.execute(new RunnableClazz());


请注意,在服务器启动期间,我只创建一次执行程序。我粘贴它只是为了给我一个关于如何创建它的想法。
因此,executor.execute(new RunnableClazz());会造成问题。

最佳答案

我复制了代码并开始调试。

当您调用super.run()时,它将从ThreadPoolExecutor中运行一个:

    public void run() {
        runWorker(this);
    }


然后,runWorker调用RunnableClazz.run(),完成后,它将线程置于保留状态,等待新的可运行对象被执行。这是怎么发生的?

在threadFactory中,我假设它是这样的:

public Thread newThread(Runnable r) {
    return new ThreadAA(r);
}


Runnable r不是您的RunnableClazz,而是ThreadPoolExecutor。

编辑:

您可能要扩展ThreadPoolExecutor类并实现方法:

protected void beforeExecute(Thread t, Runnable r) { }

protected void afterExecute(Runnable r, Throwable t) { }


并在那里进行计数。

10-04 17:49