سؤال

أي أفكار حول كيفية تحديد عدد سلاسل الرسائل النشطة قيد التشغيل حاليًا في ملف ExecutorService?

هل كانت مفيدة؟

المحلول

إستخدم ThreadPoolExecutor التنفيذ والدعوة getActiveCount() عليه:

int getActiveCount() 
// Returns the approximate number of threads that are actively executing tasks.

لا توفر واجهة ExecutorService طريقة لذلك، فهي تعتمد على التنفيذ.

نصائح أخرى

على افتراض pool هو اسم مثيل ExecutorService:

if (pool instanceof ThreadPoolExecutor) {
    System.out.println(
        "Pool size is now " +
        ((ThreadPoolExecutor) pool).getActiveCount()
    );
}

تحقق من الكود المصدري لـ Executors.newFixedThreadPool():

return new ThreadPoolExecutor(nThreads, nThreads,
                              0L, TimeUnit.MILLISECONDS,
                              new LinkedBlockingQueue<Runnable>());

يحتوي ThreadPoolExecutor على طريقة getActiveCount().لذلك يمكنك إما إرسال ExecutorService إلى ThreadPoolExecutor، أو استخدام الكود أعلاه مباشرة للحصول على واحد.يمكنك بعد ذلك استدعاء getActiveCount().

لا تحدد واجهة ExecutorService طريقة لفحص عدد سلاسل العمليات العاملة في التجمع، لأن هذه تفاصيل التنفيذ

public int getPoolSize()
Returns the current number of threads in the pool.

متاح في فئة ThreadPoolExecutor

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class PoolSize {

    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue());
        System.out.println(executor.getPoolSize());
    }
}

ولكن هذا يتطلب منك إنشاء ThreadPoolExecutor بشكل صريح، بدلاً من استخدام مصنع Executors الذي يقوم بإرجاع كائنات ExecutorService.يمكنك دائمًا إنشاء المصنع الخاص بك الذي يقوم بإرجاع ThreadPoolExecutors، ولكن سيظل أمامك الشكل السيئ لاستخدام النوع الملموس، وليس الواجهة الخاصة به.

أحد الاحتمالات هو توفير ThreadFactory الخاص بك والذي يقوم بإنشاء سلاسل رسائل في مجموعة سلاسل رسائل معروفة، والتي يمكنك بعد ذلك حسابها

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;


public class PoolSize2 {

    public static void main(String[] args) {
        final ThreadGroup threadGroup = new ThreadGroup("workers");

        ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
            public Thread newThread(Runnable r) {
                return new Thread(threadGroup, r);
            }
        });

        System.out.println(threadGroup.activeCount());
    }
}

لقد واجهت نفس المشكلة، لذا قمت بإنشاء Runnable بسيط لتتبع مثيل ExecutorService.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;

public class ExecutorServiceAnalyzer implements Runnable
{
    private final ThreadPoolExecutor threadPoolExecutor;
    private final int timeDiff;

    public ExecutorServiceAnalyzer(ExecutorService executorService, int timeDiff)
    {
        this.timeDiff = timeDiff;
        if (executorService instanceof ThreadPoolExecutor)
        {
            threadPoolExecutor = (ThreadPoolExecutor) executorService;
        }
        else
        {
            threadPoolExecutor = null;
            System.out.println("This executor doesn't support ThreadPoolExecutor ");
        }

    }

    @Override
    public void run()
    {
        if (threadPoolExecutor != null)
        {
            do
            {
                System.out.println("#### Thread Report:: Active:" + threadPoolExecutor.getActiveCount() + " Pool: "
                        + threadPoolExecutor.getPoolSize() + " MaxPool: " + threadPoolExecutor.getMaximumPoolSize()
                        + " ####");
                try
                {
                    Thread.sleep(timeDiff);
                }
                catch (Exception e)
                {
                }
            } while (threadPoolExecutor.getActiveCount() > 1);
            System.out.println("##### Terminating as only 1 thread is active ######");
        }

    }
}

يمكنك ببساطة استخدام هذا مع المنفذ الخاص بك للحصول على حالات ThreadPool

السابق

ExecutorService executorService = Executors.newFixedThreadPool(4);
    executorService.execute(new ExecutorServiceAnalyzer(executorService, 1000));

ضع عدادًا متطايرًا ثابتًا على الخيط والذي يتم تحديثه كلما تم تنشيط الخيط وإلغاء تنشيطه.راجع أيضًا واجهة برمجة التطبيقات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top