知识库--如何将线程池中的线程退出(115)

使用工厂方法的一个class

public class EnergySource {
private final long MAXLEVEL = 100;
private long level = MAXLEVEL;
private static final ScheduledExecutorService replenishTimer =
        Executors.newScheduledThreadPool(10);
private ScheduledFuture<?> replenishTask;

private EnergySource() {
}

private void init() {
    replenishTask = replenishTimer.scheduleAtFixedRate(new Runnable() {
        public void run() {
            replenish();
        }
    }, 0, 1, TimeUnit.SECONDS);
}

public static EnergySource create() {
    final EnergySource energySource = new EnergySource();
    energySource.init();
    return energySource;
}

public long getUnitsAvailable() {
    return level;
}

public boolean useEnergy(final long units) {
    if (units > 0 && level >= units) {
        level -= units;
        return true;
    }
    return false;
}

public void stopEnergySource() {
    replenishTask.cancel(false);
}

private void replenish() {
    if (level < MAXLEVEL) level++;
}

}

//线程池中的线程默认为非守护线程,jvm不能做什么
Making the replenishTimer field static helped us share the pool of threads in the ScheduledThreadPoolExecutor. However, this leads to one complication: we have to figure out a way to shut it down. By default the executor threads run as nondaemon threads and will prevent the shutdown of the JVM if we don’t explicitly shut them down.

方法1 使用静态方法

public static void shutdown() { replenishTimer.shutdown(); }

There are two problems with this approach. The users of the EnergySource
have to remember to call this method. We also have to add logic to deal
with instances of EnergySource being created after the call to shutdown().

方法2 、add线程工厂参数 生成守护线程
We may pass an additional ThreadFactory parameter to the newScheduledThreadPool() method. This factory can ensure all the threads created are daemon threads, like so:

    private static final ScheduledExecutorService replenishTimer =
        Executors.newScheduledThreadPool(10,
                new java.util.concurrent.ThreadFactory() {
                    public Thread newThread(Runnable runnable) {
                        Thread thread = new Thread(runnable);
                        thread.setDaemon(true);
                        return thread;
                    }
                });

The main disadvantage of this approach is more code for us to write and maintain.

//guava api提供了一种自动退出的线程池
The Google Guava API (http://code.google.com/p/guava-libraries/), which provides quite a few convenience wrappers on top of the JDK concurrency API, also provides a method to create pools that exits automatically.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 要获取自定义线程池线程,可以使用`ThreadPoolExecutor`类的`getActiveCount()`方法来获取当前线程池正在执行任务的线程数量,再使用`ThreadPoolExecutor`类的`getPoolSize()`方法来获取当前线程池线程总数。代码示例如下: ```java import java.util.concurrent.*; public class CustomThreadPool { public static void main(String[] args) { // 创建自定义线程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 4, 100, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10) ); // 提交任务 for (int i = 0; i < 6; i++) { executor.execute(new Task(i)); } // 获取线程池正在执行任务的线程数量 int activeCount = executor.getActiveCount(); System.out.println("当前线程池正在执行任务的线程数量:" + activeCount); // 获取线程池线程总数 int poolSize = executor.getPoolSize(); System.out.println("当前线程池线程总数:" + poolSize); // 关闭线程池 executor.shutdown(); } } class Task implements Runnable { private int taskId; public Task(int taskId) { this.taskId = taskId; } @Override public void run() { System.out.println("任务 " + taskId + " 正在执行..."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任务 " + taskId + " 执行完成!"); } } ``` 上述代码,`CustomThreadPool`类创建了一个自定义线程池`executor`,并提交了6个任务。然后使用`executor.getActiveCount()`方法和`executor.getPoolSize()`方法获取当前线程池线程数量信息,并打印输出。最后关闭线程池。 ### 回答2: 在Java,我们可以通过以下步骤来获取自定义线程池线程: 1. 首先,我们需要创建一个自定义的线程池对象。可以使用ThreadPoolExecutor类来实现一个自定义线程池,该类提供了许多可调整的参数,例如核心线程数、最大线程数、闲置线程存活时间等等。 2. 在创建自定义线程池对象之后,我们可以通过调用execute()方法将任务提交到线程池。execute()方法接受一个Runnable对象作为参数,该对象代表一个待执行的任务。 3. 如果我们想获取线程池线程,可以调用线程池对象的getPoolSize()方法,该方法返回当前线程池线程数量。这可以帮助我们了解线程池的使用情况。 4. 另外,如果我们想获取线程池的每个线程的详细信息,可以通过调用线程池对象的getActiveThreads()方法来获取活动线程的数组。然后,我们可以遍历该数组以获取每个线程的相关信息,例如线程的ID、名称等等。 总结起来,要获取自定义线程池线程,我们需要创建一个自定义线程池对象,然后通过调用相应的方法来获取线程池线程的数量或者每个线程的详细信息。这样,我们可以更好地了解线程池的使用情况,并且对线程池的调度和管理进行更精确的控制。 ### 回答3: Java获取自定义线程池线程可以通过ThreadPoolExecutor类的getActiveCount()和getPoolSize()方法来实现。 首先,我们需要先创建一个自定义的线程池对象,例如: ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); 其corePoolSize为线程池核心线程的数量,maximumPoolSize为线程池允许的最大线程数量,keepAliveTime为线程空闲时的存活时间,unit为存活时间的单位,workQueue为任务队列,用于存放待执行的任务。 接下来,我们使用executor对象可以调用getActiveCount()方法来获取当前活动的线程数量,即正在执行任务的线程数量。示例代码如下: int activeThreadCount = executor.getActiveCount(); 同时,我们还可以使用getPoolSize()方法来获取当前线程池线程数量,包括核心线程和非核心线程。示例代码如下: int threadPoolSize = executor.getPoolSize(); 这样,我们就可以通过上述方法获得自定义线程池线程的数量了。 需要注意的是,使用线程池时要注意及时关闭线程池,以免引发线程泄漏或资源浪费的问题。可以通过调用executor.shutdown()方法来关闭线程池。 总之,我们可以通过ThreadPoolExecutor类的getActiveCount()和getPoolSize()方法来获取自定义线程池线程的数量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自驱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值