2016-02-24 8 views
5

क्या जावा 8 के Executors.newWorkStealingPool() के साथ संयोजन में लंबित कार्यों की एक कतार है?जावा 8 में, execors.newWorkStealingPool() भी कार्य कतार प्रदान करता है?

उदाहरण के लिए, मान लें कि # उपलब्ध कोर 2 है, और Executors.newWorkStealingPool() खाली है क्योंकि 2 कार्य पहले से चल रहे हैं। फिर क्या होता है यदि कार्य-चोरी निष्पादक को तीसरा कार्य सबमिट किया जाता है? क्या यह कतारबद्ध है? और यदि यह है, तो कहा गया कतार में कोई सीमा क्या है?

अग्रिम धन्यवाद।

+1

मेरे पास कोई विशिष्ट उत्तर नहीं है, और मुझे आश्चर्य है कि यह बेहतर दस्तावेज नहीं है। लेकिन कम से कम ओपनजेडीके 8 में, यह विधि एक ['फोर्कजोइनपूल'] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool बनाती है।एचटीएमएल), जो कि अन्य कार्यान्वयन के रूप में 'ब्लॉकिंग क्यूयू' का उपयोग नहीं करता है ... जो बहुत अधिक विवाद का कारण बनता है, जिससे उपरिवर्तित होता है। कार्य जिन्हें तत्काल निष्पादित नहीं किया जा सकता * * अभी भी कतारबद्ध हैं। इस पर चर्चा की गई है (कतार सीमाओं के साथ) एक और जवाब में: http://stackoverflow.com/a/30045601/228171 –

उत्तर

4

क्या जावा 8 के एक्जिक्यूटर्स.न्यूवॉर्क्सस्टेलिंगपूल() के साथ संयोजन में लंबित कार्यों का कतार है?

हां, प्रत्येक धागे को अपने स्वयं के डेक के साथ समर्थित किया जाता है। जब एक थ्रेड अपने कार्यों के साथ किया जाता है तो यह अन्य धागे के डेक से कार्य करता है और इसे निष्पादित करता है।

और यदि यह है, तो कहा गया कतार में कोई सीमा क्या है?

कतारों के लिए अधिकतम आकार संख्या से सीमित है: जब कतार भर गई है static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M

एक अनियंत्रित अपवाद फेंक दिया जाता है: RejectedExecutionException("Queue capacity exceeded")

3

Executors की grepcode से और ForkJoinPool

ExecutorsnewWorkStealingPool रिटर्न ForkJoinPool

निष्पादकों:

public static ExecutorService newWorkStealingPool() { 
     return new ForkJoinPool 
      (Runtime.getRuntime().availableProcessors(), 
      ForkJoinPool.defaultForkJoinWorkerThreadFactory, 
      null, true); 
    } 

ForkJoinPool:

public ForkJoinPool(int parallelism, 
         ForkJoinWorkerThreadFactory factory, 
         UncaughtExceptionHandler handler, 
         boolean asyncMode) { 
     this(checkParallelism(parallelism), 
      checkFactory(factory), 
      handler, 
      asyncMode ? FIFO_QUEUE : LIFO_QUEUE, 
      "ForkJoinPool-" + nextPoolId() + "-worker-"); 
     checkPermission(); 
    } 

पर execute():

public void execute(ForkJoinTask<?> task) { 
     if (task == null) 
      throw new NullPointerException(); 
     externalPush(task); 
    } 

externalPushexternalSubmit पर कॉल करता है और आप उस कार्यान्वयन में WorkQueue विवरण देख सकते हैं।

externalSubmit:

// बाहरी संचालन

/** 
* Full version of externalPush, handling uncommon cases, as well 
* as performing secondary initialization upon the first 
* submission of the first task to the pool. It also detects 
* first submission by an external thread and creates a new shared 
* queue if the one at index if empty or contended. 
* 
* @param task the task. Caller must ensure non-null. 

*/ 

आप WokrQueue पर WorkQueue वर्ग

static final class WorkQueue { 

प्रलेखन में कतार आकार के बारे में और अधिक जानकारी प्राप्त कर सकते हैं:

/** 
    * Queues supporting work-stealing as well as external task 
    * submission. See above for descriptions and algorithms. 
    * Performance on most platforms is very sensitive to placement of 
    * instances of both WorkQueues and their arrays -- we absolutely 
    * do not want multiple WorkQueue instances or multiple queue 
    * arrays sharing cache lines. The @Contended annotation alerts 
    * JVMs to try to keep instances apart. 
    */ 
    @sun.misc.Contended 

/** 
    * Capacity of work-stealing queue array upon initialization. 
    * Must be a power of two; at least 4, but should be larger to 
    * reduce or eliminate cacheline sharing among queues. 
    * Currently, it is much larger, as a partial workaround for 
    * the fact that JVMs often place arrays in locations that 
    * share GC bookkeeping (especially cardmarks) such that 
    * per-write accesses encounter serious memory contention. 
    */ 
    static final int INITIAL_QUEUE_CAPACITY = 1 << 13; 

    /** 
    * Maximum size for queue arrays. Must be a power of two less 
    * than or equal to 1 << (31 - width of array entry) to ensure 
    * lack of wraparound of index calculations, but defined to a 
    * value a bit less than this to help users trap runaway 
    * programs before saturating systems. 
    */ 
    static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M 
संबंधित मुद्दे