GVKun编程网logo

newFixedThreadPool与newSingleThreadExecutor的性能问题(newfixedthreadpool参数都有哪些)

30

在本文中,我们将详细介绍newFixedThreadPool与newSingleThreadExecutor的性能问题的各个方面,并为您提供关于newfixedthreadpool参数都有哪些的相关解

在本文中,我们将详细介绍newFixedThreadPool与newSingleThreadExecutor的性能问题的各个方面,并为您提供关于newfixedthreadpool参数都有哪些的相关解答,同时,我们也将为您带来关于CachedThreadPool/FixedThreadPool/SingleThreadExecu、com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor的实例源码、Executors.newCachedThreadPool 源码解析、Executors.newCachedThreadPool() 与 Executors.newFixedThreadPool()的有用知识。

本文目录一览:

newFixedThreadPool与newSingleThreadExecutor的性能问题(newfixedthreadpool参数都有哪些)

newFixedThreadPool与newSingleThreadExecutor的性能问题(newfixedthreadpool参数都有哪些)

我正在尝试对我们的客户代码进行基准测试。因此,我决定编写一个多线程程序来对我的客户端代码进行基准测试。我正在尝试测量time (95Percentile)下面的方法需要多少?

attributes = deClient.getDEAttributes(columnsList);

因此,下面是我编写的用于对上述方法进行基准测试的多线程代码。在两种情况下,我看到了很多变化-

1)首先,使用20 threads和来处理多线程代码running for 15 minutes。我得到95%的37ms。我正在使用-

ExecutorService service = Executors.newFixedThreadPool(20);

2)但是,如果我运行相同的程序以15 minutes使用-

ExecutorService service = Executors.newSingleThreadExecutor();

代替

ExecutorService service = Executors.newFixedThreadPool(20);

7ms当我使用运行代码时,我得到95%,比上面的数字要少得多newFixedThreadPool(20)

谁能告诉我以下原因导致此类高性能问题的原因是什么?

newSingleThreadExecutor vs newFixedThreadPool(20)

而且通过两种方式我都运行我的程序15 minutes

以下是我的代码-

public static void main(String[] args) {    try {        // create thread pool with given size        //ExecutorService service = Executors.newFixedThreadPool(20);        ExecutorService service = Executors.newSingleThreadExecutor();        long startTime = System.currentTimeMillis();        long endTime = startTime + (15 * 60 * 1000);//Running for 15 minutes        for (int i = 0; i < threads; i++) {            service.submit(new ServiceTask(endTime, serviceList));        }        // wait for termination                service.shutdown();        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);    } catch (InterruptedException e) {    } catch (Exception e) {    }}

下面是实现Runnable接口的类-

class ServiceTask implements Runnable {    private static final Logger LOG = Logger.getLogger(ServiceTask.class.getName());    private static Random random = new SecureRandom();    public static volatile AtomicInteger countSize = new AtomicInteger();    private final long endTime;    private final LinkedHashMap<String, ServiceInfo> tableLists;    public static ConcurrentHashMap<Long, Long> selectHistogram = new ConcurrentHashMap<Long, Long>();    public ServiceTask(long endTime, LinkedHashMap<String, ServiceInfo> tableList) {        this.endTime = endTime;        this.tableLists = tableList;    }    @Override    public void run() {        try {            while (System.currentTimeMillis() <= endTime) {                double randomNumber = random.nextDouble() * 100.0;                ServiceInfo service = selectRandomService(randomNumber);                final String id = generateRandomId(random);                final List<String> columnsList = getColumns(service.getColumns());                List<DEAttribute<?>> attributes = null;                DEKey bk = new DEKey(service.getKeys(), id);                List<DEKey> list = new ArrayList<DEKey>();                list.add(bk);                Client deClient = new Client(list);                final long start = System.nanoTime();                attributes = deClient.getDEAttributes(columnsList);                final long end = System.nanoTime() - start;                final long key = end / 1000000L;                boolean done = false;                while(!done) {                    Long oldValue = selectHistogram.putIfAbsent(key, 1L);                    if(oldValue != null) {                        done = selectHistogram.replace(key, oldValue, oldValue + 1);                    } else {                        done = true;                    }                }                countSize.getAndAdd(attributes.size());                handleDEAttribute(attributes);                if (BEServiceLnP.sleepTime > 0L) {                    Thread.sleep(BEServiceLnP.sleepTime);                }            }        } catch (Exception e) {        }    }}

更新:-

这是我的处理器规格-我正在Linux机器上运行程序,其中2个处理器定义为:

vendor_id       : GenuineIntelcpu family      : 6model           : 45model name      : Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHzstepping        : 7cpu MHz         : 2599.999cache size      : 20480 KBfpu             : yesfpu_exception   : yescpuid level     : 13wp              : yesflags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes hypervisor lahf_lm arat pln ptsbogomips        : 5199.99clflush size    : 64cache_alignment : 64address sizes   : 40 bits physical, 48 bits virtualpower management:

答案1

小编典典

谁能告诉我newSingleThreadExecutorvs 如此高性能问题的原因是什么newFixedThreadPool(20)

如果并行运行的任务(如果是20个)比处理器(我怀疑您有20个以上的处理器)要多得多,那么是的,每个单独的任务将需要更长的时间才能完成。对于计算机而言,一次执行一个任务比在同时运行的多个线程之间切换要容易得多。即使将池中的线程数限制为拥有的CPU数,每个任务的运行速度可能也会变慢,尽管会略有降低。

但是,如果比较不同大小的线程池的 吞吐量
(完成多个任务所需的时间),则应该看到20个线程的吞吐量应该更高。如果您用20个线程执行1000个任务,则总体而言,完成任务要比仅使用1个线程快得多。每个任务可能需要更长的时间,但它们将并行执行。给定线程开销等,它可能不会快20倍,但是可能快15倍。

您不必担心单个任务的速度,而应该通过调整池中的线程数来尝试最大化任务吞吐量。使用多少线程在很大程度上取决于IO数量,每个任务使用的CPU周期,锁,同步块,在OS上运行的其他应用程序以及其他因素。

就池中的线程数而言,人们通常会使用1-2倍的CPU作为启动内存的最佳位置,以最大程度地提高吞吐量。更多的IO请求或线程阻塞操作将添加更多的线程。更多的CPU绑定将减少线程数,使其更接近可用的CPU数。如果您的应用程序正在与服务器上其他更重要的应用程序竞争OS周期,则可能需要更少的线程。

CachedThreadPool/FixedThreadPool/SingleThreadExecu

CachedThreadPool/FixedThreadPool/SingleThreadExecu

1. CachedThreadPool会创建尽可能为每一个提交的runnable创建一个线程,如果有空闲线程则优先利用空闲线程。

2.FixedThreadPool创建确定数量的线程。

3.创建一个线程。

线程池如何回收旧线程?

com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor的实例源码

com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor的实例源码

项目:gallery    文件:GlideSetup.java   
@Override
public void applyOptions(Context context,GlideBuilder builder) {
    //builder.setMemoryCache(new LruResourceCache(64 * 1024 * 1024));
    //builder.setBitmapPool(new LruBitmapPool(32 * 1024 * 1024));
    builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    builder.setdiskCache(new InternalCachediskCacheFactory(context,2147483647));
    builder.setResizeService(new FifoPriorityThreadPoolExecutor(2));
}
项目:Moegallery    文件:GlideSetup.java   
@Override
public void applyOptions(Context context,2147483647));
    builder.setResizeService(new FifoPriorityThreadPoolExecutor(2));
}
项目:glide-support    文件:GlideModule.java   
@Override public void applyOptions(Context context,GlideBuilder builder) {
    //if (VERSION.SDK_INT == VERSION_CODES.KITKAT)
    builder.setResizeService(new FifoPriorityThreadPoolExecutor(4));
}
项目:glide-support    文件:GlideModule.java   
@Override public void applyOptions(Context context,GlideBuilder builder) {
    // debug: make sure there's enough threads so delay transformations don't block the others
    builder.setdiskCacheService(new FifoPriorityThreadPoolExecutor(20));
    builder.setResizeService(new FifoPriorityThreadPoolExecutor(20));
}

Executors.newCachedThreadPool 源码解析

Executors.newCachedThreadPool 源码解析

Executors 还有个常用静态方法 newCachedThreadPool (),来构造线程池 今天我们其源码实现,探一探究竟

//底层还是调用ThreadPoolExecutor,不过参数有变化
//corePoolSize 竟然为0,maximumPoolSize为默认的最大值
//当任务队列满时,就会判断maximumPoolSize大小
//keepAliveTime 空闲线程的最大等待时间,,60s后立马销毁线程了
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

####SynchronousQueue 注意这个队列

A {@linkplain BlockingQueue blocking queue} in which each insert
 * operation must wait for a corresponding remove operation by another
 * thread, and vice versa.  A synchronous queue does not have any
 * internal capacity, not even a capacity of one. 
  • SynchronousQueue,实际上它不是一个真正的队列,因为它不会为队列中元素维护存储空间。与其他队列不同的是,它维护一组线程,这些线程在等待着把元素加入或移出队列。
  • 在使用 SynchronousQueue 作为工作队列的前提下,客户端代码向线程池提交任务时,而线程池中又没有空闲的线程能够从 SynchronousQueue 队列实例中取一个任务,那么相应的 offer 方法调用就会失败(即任务没有被存入工作队列)。此时,ThreadPoolExecutor 会新建一个新的工作者线程用于对这个入队列失败的任务进行处理(假设此时线程池的大小还未达到其最大线程池大小 maximumPoolSize)。

newFixedThreadPool 和 newCachedThreadPool 最大差别就是 队列,线程回收的时间

###newFixedThreadPool 应用场景

 Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available.  These pools will typically improve the performance
     * of programs that execute many short-lived asynchronous tasks.
     * Calls to <tt>execute</tt> will reuse previously constructed
     * threads if available. If no existing thread is available, a new
     * thread will be created and added to the pool. Threads that have
     * not been used for sixty seconds are terminated and removed from
     * the cache. Thus, a pool that remains idle for long enough will
     * not consume any resources.

newFixedThreadPool 线程池的数量是不确定的,可以无限大。 它比较适合处理执行时间比较小的任务

Executors.newCachedThreadPool() 与 Executors.newFixedThreadPool()

Executors.newCachedThreadPool() 与 Executors.newFixedThreadPool()

newCachedThreadPool()相对newFixedThreadPool()

我什么时候应该使用其中一种?在资源利用方面哪种策略更好?

答案1

小编典典

我认为文档很好地解释了这两个函数的区别和用法:

newFixedThreadPool

创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程。在任何时候,最多 nThreads
个线程将是活动的处理任务。如果在所有线程都处于活动状态时提交了其他任务,它们将在队列中等待,直到有线程可用。如果任何线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,新的线程将取代它。池中的线程将一直存在,直到显式关闭。

newCachedThreadPool

创建一个线程池,根据需要创建新线程,但在可用时将重用以前构造的线程。这些池通常会提高执行许多短期异步任务的程序的性能。如果可用,对执行的调用将重用以前构造的线程。如果没有可用的现有线程,将创建一个新线程并将其添加到池中。六十秒内未使用的线程将被终止并从缓存中删除。因此,保持空闲足够长时间的池不会消耗任何资源。请注意,可以使用
ThreadPoolExecutor 构造函数创建具有相似属性但细节不同(例如超时参数)的池。

在资源方面,newFixedThreadPool它将保持所有线程运行,直到它们被显式终止。在newCachedThreadPool60
秒内未使用的线程将被终止并从缓存中删除。

鉴于此,资源消耗将在很大程度上取决于具体情况。例如,如果您有大量长时间运行的任务,我建议使用FixedThreadPool.
至于CachedThreadPool,文档说“这些池通常会提高执行许多短期异步任务的程序的性能”。

今天的关于newFixedThreadPool与newSingleThreadExecutor的性能问题newfixedthreadpool参数都有哪些的分享已经结束,谢谢您的关注,如果想了解更多关于CachedThreadPool/FixedThreadPool/SingleThreadExecu、com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor的实例源码、Executors.newCachedThreadPool 源码解析、Executors.newCachedThreadPool() 与 Executors.newFixedThreadPool()的相关知识,请在本站进行查询。

本文标签: