জাভা 8 সমান্তরাল স্ট্রিমের কাস্টম থ্রেড পুল


398

জাভা 8 সমান্তরাল স্ট্রিমের জন্য কাস্টম থ্রেড পুল নির্দিষ্ট করা সম্ভব ? আমি এটা কোথাও খুঁজে পাচ্ছি না.

কল্পনা করুন যে আমার একটি সার্ভার অ্যাপ্লিকেশন রয়েছে এবং আমি সমান্তরাল স্ট্রিমগুলি ব্যবহার করতে চাই। তবে অ্যাপ্লিকেশনটি বড় এবং একাধিক-থ্রেডযুক্ত তাই আমি এটিটি বিভাগ করতে চাই। আমি অন্য মডিউল থেকে অ্যাপ্লিকেশন কর্মের একটি মডিউলটিতে একটি ধীর চলমান কাজ চাই না।

যদি আমি বিভিন্ন মডিউলগুলির জন্য বিভিন্ন থ্রেড পুল ব্যবহার করতে না পারি তবে এর অর্থ আমি বিশ্বের বেশিরভাগ পরিস্থিতিতে নিরাপদে সমান্তরাল স্ট্রিম ব্যবহার করতে পারি না।

নিম্নলিখিত উদাহরণ চেষ্টা করুন। পৃথক থ্রেডে কিছু সিপিইউ নিবিড় কাজ সম্পাদিত হয়েছে। কাজগুলি সমান্তরাল স্ট্রিমগুলির উত্তোলন করে। প্রথম টাস্কটি নষ্ট হয়ে গেছে, তাই প্রতিটি পদক্ষেপে 1 সেকেন্ড লাগে (থ্রেড স্লিপ দ্বারা সিমুলেটেড)। সমস্যাটি হ'ল অন্যান্য থ্রেড আটকে যায় এবং ভাঙ্গা কাজ শেষ হওয়ার জন্য অপেক্ষা করে। এটি নিখুঁত উদাহরণ, তবে কোনও সার্লেট অ্যাপ এবং কল্পনা করুন যে কেউ ভাগ করে নেওয়া কাঁটাচামচ যোগদানের পুলটিতে দীর্ঘ কাজ চালাচ্ছেন ting

public class ParallelTest {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService es = Executors.newCachedThreadPool();

        es.execute(() -> runTask(1000)); //incorrect task
        es.execute(() -> runTask(0));
        es.execute(() -> runTask(0));
        es.execute(() -> runTask(0));
        es.execute(() -> runTask(0));
        es.execute(() -> runTask(0));


        es.shutdown();
        es.awaitTermination(60, TimeUnit.SECONDS);
    }

    private static void runTask(int delay) {
        range(1, 1_000_000).parallel().filter(ParallelTest::isPrime).peek(i -> Utils.sleep(delay)).max()
                .ifPresent(max -> System.out.println(Thread.currentThread() + " " + max));
    }

    public static boolean isPrime(long n) {
        return n > 1 && rangeClosed(2, (long) sqrt(n)).noneMatch(divisor -> n % divisor == 0);
    }
}

3
কাস্টম থ্রেড পুল বলতে কী বোঝ? এখানে একক সাধারণ ফর্কজইনপুল রয়েছে তবে আপনি সর্বদা আপনার নিজের ফোর্কজইনপুল তৈরি করতে এবং এতে অনুরোধ জমা দিতে পারেন।

7
ইঙ্গিত: জাভা চ্যাম্পিয়ন হেইঞ্জ কাবুটজ একই সমস্যাটি পর্যালোচনা করে তবে আরও খারাপ প্রভাব নিয়ে: সাধারণ কাঁটাচামড়ার জোড় সংলগ্ন থ্রেডকে ডিডলকিং করে। দেখুন javaspecialists.eu/archive/Issue223.html
Peti

উত্তর:


395

একটি নির্দিষ্ট কাঁটাচামচ-জলের পুলে কীভাবে একটি সমান্তরাল অপারেশন চালানো যায় তা আসলে একটি কৌশল। যদি আপনি এটি কাঁটাচামচ পুলে কোনও কাজ হিসাবে চালিত করেন তবে এটি সেখানে থাকে এবং সাধারণটি ব্যবহার করে না।

final int parallelism = 4;
ForkJoinPool forkJoinPool = null;
try {
    forkJoinPool = new ForkJoinPool(parallelism);
    final List<Integer> primes = forkJoinPool.submit(() ->
        // Parallel task here, for example
        IntStream.range(1, 1_000_000).parallel()
                .filter(PrimesPrint::isPrime)
                .boxed().collect(Collectors.toList())
    ).get();
    System.out.println(primes);
} catch (InterruptedException | ExecutionException e) {
    throw new RuntimeException(e);
} finally {
    if (forkJoinPool != null) {
        forkJoinPool.shutdown();
    }
}

কৌতুকটি ফোর্কজাইনটাস্ক.ফোর্কের উপর ভিত্তি করে তৈরি করা হয়েছে যা উল্লেখ করে: " পুলটিতে এই কাজটি সিকোয়েনসিভভাবে সম্পাদনের ব্যবস্থা রয়েছে, যদি প্রযোজ্য হয়, বা ফোরকজয়াইনপুল.কমপল () ইনফোকজাইনপুল ব্যবহার না করে () ব্যবহার করে তবে"


20
সমাধানের বিশদটি
লুকাশ

3
তবে এটি কি সুনির্দিষ্ট করে যে স্ট্রিমগুলি ব্যবহার করে ForkJoinPoolবা এটি বাস্তবায়নের বিশদ? ডকুমেন্টেশনের একটি লিঙ্ক সুন্দর হবে।
নিকোলাই

6
@ লুকাস স্নিপেটের জন্য ধন্যবাদ। আমি যুক্ত করব যে থ্রেড ফাঁস এড়াতে যখন আর প্রয়োজন হয় না তখন ForkJoinPoolউদাহরণটি হওয়া উচিত shutdown()(উদাহরণস্বরূপ)
জ্যাক

5
নোট করুন জাভা 8-তে একটি বাগ রয়েছে যে কাস্টম পুলের উদাহরণস্বরূপ কাজগুলি চলমান থাকলেও সেগুলি এখনও ভাগ করা পুলের সাথে মিলিত হয়েছে: গণনার আকার কমন পুলের সাথে না মিলিয়ে সাধারণ পুলের অনুপাতে থেকে যায়। জাভা 10 এ স্থির করা হয়েছিল: জেডিকে-8190974
টেরান

3
@ ইটারান এই সমস্যাটি জাভা 8 বাগের
বাগ.ওপেনজডক.জাভা.

192

সমান্তরাল স্ট্রিমগুলি ডিফল্টটি ব্যবহার করে ForkJoinPool.commonPoolযা আপনার প্রসেসরগুলির হিসাবে ডিফল্টরূপে একটি কম থ্রেড থাকে , যেমনটি ফিরে আসে Runtime.getRuntime().availableProcessors()(এর অর্থ সমান্তরাল স্ট্রিমগুলি আপনার সমস্ত প্রসেসর ব্যবহার করে কারণ তারা মূল থ্রেডও ব্যবহার করে):

অ্যাপ্লিকেশনগুলির জন্য যা পৃথক বা কাস্টম পুলের প্রয়োজন, একটি নির্দিষ্ট লক্ষ্য সমান্তরালতা স্তর দিয়ে একটি ফোর্কজাইনপুল নির্মিত হতে পারে; ডিফল্টরূপে, উপলব্ধ প্রসেসরের সংখ্যার সমান।

এর অর্থ হ'ল যদি আপনি সমান্তরাল স্ট্রিমগুলি বা একাধিক সমান্তরাল স্ট্রিমগুলি একই সাথে শুরু করে থাকেন তবে তারা সকলেই একই পুল ভাগ করে নেবে । সুবিধা: আপনি কখনই ডিফল্ট (উপলব্ধ প্রসেসরের সংখ্যা) এর চেয়ে বেশি ব্যবহার করবেন না। অসুবিধা: আপনি শুরু করা প্রতিটি সমান্তরাল স্ট্রিমের জন্য নিয়োগ করা "সমস্ত প্রসেসর" নাও পেতে পারেন (যদি আপনার একাধিক সংখ্যক থাকে)। (স্পষ্টতই আপনি এটি রোধ করার জন্য একটি ম্যানেজডব্লকার ব্যবহার করতে পারেন ))

সমান্তরাল স্ট্রিমগুলি সম্পাদন করার উপায়টি পরিবর্তন করতে আপনি হয় তা করতে পারেন

  • সমান্তরাল স্ট্রিম এক্সিকিউশনটি আপনার নিজের ফোর্কজইনপুলে জমা দিন: yourFJP.submit(() -> stream.parallel().forEach(soSomething)).get();বা
  • আপনি সিস্টেমের বৈশিষ্ট্য ব্যবহার করে সাধারণ পুলের আকার পরিবর্তন করতে পারেন: System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20")20 টি থ্রেডের লক্ষ্য সমান্তরালতার জন্য। তবে এটি আর ব্যাকপোর্টেড প্যাচ https://bugs.openjdk.java.net/browse/JDK-8190974 এর পরে আর কাজ করে না ।

আমার মেশিনে আধুনিকতার উদাহরণ যার মধ্যে 8 টি প্রসেসর রয়েছে। আমি যদি নিম্নলিখিত প্রোগ্রামটি চালিত করি:

long start = System.currentTimeMillis();
IntStream s = IntStream.range(0, 20);
//System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20");
s.parallel().forEach(i -> {
    try { Thread.sleep(100); } catch (Exception ignore) {}
    System.out.print((System.currentTimeMillis() - start) + " ");
});

আউটপুটটি হ'ল:

215 216 216 216 216 216 216 216 315 316 316 316 316 316 316 316 415 416 416 416

সুতরাং আপনি দেখতে পারেন যে সমান্তরাল স্ট্রিমটি একসাথে 8 টি আইটেম প্রক্রিয়াকরণ করে, অর্থাৎ এটি 8 টি থ্রেড ব্যবহার করে। যাইহোক, আমি মন্তব্য করা লাইনটি uncomment করে, আউটপুট হয়:

215 215 215 215 215 216 216 216 216 216 216 216 216 216 216 216 216 216 216 216

এবার সমান্তরাল স্ট্রিমটি 20 টি থ্রেড ব্যবহার করেছে এবং স্ট্রিমের সমস্ত 20 টি উপাদান একই সাথে প্রক্রিয়াজাত করা হয়েছে।


30
commonPoolচেয়ে এক কম আসলে হয়েছে availableProcessorsসমান, মোট উপমা ফলে availableProcessorsকারণ এক হিসাবে কলিং থ্রেড গন্য।
মার্কো টপলনিক

2
রিটার্ন জমা দিন ForkJoinTask। অনুকরণ করার parallel() get()জন্য প্রয়োজনীয়:stream.parallel().forEach(soSomething)).get();
গ্রেগরি কিসলিন

5
আমি নিশ্চিত নই যে ForkJoinPool.submit(() -> stream.forEach(...))প্রদত্তদের সাথে আমার স্ট্রিম ক্রিয়া চালাবে ForkJoinPool। আমি আশা করব যে পুরো স্ট্রিম-অ্যাকশনটি ফোরজয়াইনপুলে ওয়ান অ্যাকশন হিসাবে কার্যকর করা হয়েছে, তবে অভ্যন্তরীণভাবে এখনও ডিফল্ট / সাধারণ ফোরকজাইনপুল ব্যবহার করছে। আপনি কোথায় দেখেছেন যে ফোরকজাইনপুল.সাম্বিট () আপনি যা বলবেন তা করবে?
ফ্রেডেরিক লাইটেনবার্গার 23'18

@ ফ্রেডেরিকলিটেনবার্গার সম্ভবত আপনার মন্তব্যটি লুকাসের উত্তরের নীচে রেখেছেন to
Assylias

2
আমি এখন দেখতে পাচ্ছি স্ট্যাকওভারফ্লো.com/a/34930831/1520422 সুন্দরভাবে দেখায় যে এটি ঘোষিত হিসাবে বাস্তবে কাজ করে। তবুও আমি বুঝতে পারি না এটি কীভাবে কাজ করে। তবে আমি "এটি কাজ করে" দিয়ে ভাল আছি। ধন্যবাদ!
ফ্রেডেরিক লাইটেনবার্গার

39

বিকল্পভাবে আপনার নিজের কাঁটাচামচে জিনপুলের অভ্যন্তরে সমান্তরাল গণনা ট্রিগার করার কৌশলটির জন্য আপনি সেই পুলটি কমপ্লিটেবল ফিউচার.সপ্পলএসিঙ্ক পদ্ধতিতেও পাস করতে পারেন:

ForkJoinPool forkJoinPool = new ForkJoinPool(2);
CompletableFuture<List<Integer>> primes = CompletableFuture.supplyAsync(() ->
    //parallel task here, for example
    range(1, 1_000_000).parallel().filter(PrimesPrint::isPrime).collect(toList()), 
    forkJoinPool
);

22

আসল সমাধান (ফোরকজাইনপুল সাধারণ প্যারালালিজম সম্পত্তি সেট করে) আর কাজ করে না। মূল উত্তরের লিঙ্কগুলির দিকে তাকানো, একটি আপডেট যা এটিকে ভেঙে জাভা 8 এ পুনরায় পোর্ট করা হয়েছে লিঙ্কযুক্ত থ্রেডে উল্লিখিত হিসাবে, এই সমাধানটি চিরকালের জন্য কাজ করার গ্যারান্টিযুক্ত ছিল না। তার উপর ভিত্তি করে, সমাধানটি হ'ল forkjoinpool. સ્વીકૃત উত্তরে আলোচিত .get সমাধান সহ জমা দিন। আমি মনে করি ব্যাকপোর্ট এই সমাধানের অবিশ্বস্ততাও স্থির করে।

ForkJoinPool fjpool = new ForkJoinPool(10);
System.out.println("stream.parallel");
IntStream range = IntStream.range(0, 20);
fjpool.submit(() -> range.parallel()
        .forEach((int theInt) ->
        {
            try { Thread.sleep(100); } catch (Exception ignore) {}
            System.out.println(Thread.currentThread().getName() + " -- " + theInt);
        })).get();
System.out.println("list.parallelStream");
int [] array = IntStream.range(0, 20).toArray();
List<Integer> list = new ArrayList<>();
for (int theInt: array)
{
    list.add(theInt);
}
fjpool.submit(() -> list.parallelStream()
        .forEach((theInt) ->
        {
            try { Thread.sleep(100); } catch (Exception ignore) {}
            System.out.println(Thread.currentThread().getName() + " -- " + theInt);
        })).get();

আমি যখন ForkJoinPool.commonPool().getParallelism()ডিবাগ মোডে করি তখন সমান্তরালতার পরিবর্তন দেখতে পাই না ।
ডি-কোডার

ধন্যবাদ। আমি কিছু পরীক্ষা / গবেষণা করেছি এবং উত্তরটি আপডেট করেছি। পুরানো সংস্করণগুলিতে কাজ করে বলে কোনও আপডেট দেখে মনে হচ্ছে এটি এটি বদলেছে।
টড ক্যাসেন্ট

আমি কেন এটি পেতে থাকি: unreported exception InterruptedException; must be caught or declared to be thrownএমনকি catchলুপের সমস্ত ব্যতিক্রম ছাড়াও।
রকি লি

রকি, আমি কোনও ত্রুটি দেখছি না। জাভা সংস্করণ এবং সঠিক লাইনটি জানার সাহায্য করবে। "ইন্টারফ্রেডএক্সেপশন" পরামর্শ দেয় ঘুমের আশেপাশে চেষ্টা / ধরা আপনার সংস্করণে সঠিকভাবে বন্ধ করা হয়নি।
টড ক্যাসেন্ট

13

আমরা নিম্নলিখিত সম্পত্তি ব্যবহার করে ডিফল্ট সমান্তরালতা পরিবর্তন করতে পারি:

-Djava.util.concurrent.ForkJoinPool.common.parallelism=16

যা আরও সমান্তরালতা ব্যবহার করতে সেট আপ করতে পারে।


যদিও এটি একটি বিশ্বব্যাপী সেটিং, এটি সমান্তরাল
ধারাটি

এই openjdk সংস্করণ "1.8.0_222" এ আমার জন্য কাজ
আব্বাস

উপরের মতই ব্যক্তি, এই openjdk "11.0.6" এ আমার জন্য কাজ না করে
আব্বাস

8

ব্যবহৃত থ্রেডগুলির আসল সংখ্যা পরিমাপ করতে, আপনি যাচাই করতে পারেন Thread.activeCount():

    Runnable r = () -> IntStream
            .range(-42, +42)
            .parallel()
            .map(i -> Thread.activeCount())
            .max()
            .ifPresent(System.out::println);

    ForkJoinPool.commonPool().submit(r).join();
    new ForkJoinPool(42).submit(r).join();

এটি একটি 4-কোর সিপিইউতে আউটপুট উত্পাদন করতে পারে:

5 // common pool
23 // custom pool

.parallel()এটি দেয় ছাড়া :

3 // common pool
4 // custom pool

6
থ্রেড.এ্যাকটিভকাউন্ট () আপনাকে কী থ্রেডগুলি প্রবাহে প্রক্রিয়াকরণ করছে তা বলে না। পরিবর্তে থ্রেড.কোর্নথ্রেড ()। GetName () এর পরে মানচিত্র, তারপরে একটি পৃথক ()। তারপরে আপনি বুঝতে পারবেন যে পুলের প্রতিটি থ্রেড ব্যবহার করা হবে না ... আপনার প্রসেসিংয়ে একটি বিলম্ব যুক্ত করুন এবং পুলের সমস্ত থ্রেড ব্যবহার করা হবে।
কীক্সসি

7

এখন অবধি, আমি এই প্রশ্নের উত্তরে বর্ণিত সমাধানগুলি ব্যবহার করেছি। এখন, আমি এর জন্য সমান্তরাল স্ট্রিম সমর্থন নামে একটি ছোট লাইব্রেরি নিয়ে এসেছি :

ForkJoinPool pool = new ForkJoinPool(NR_OF_THREADS);
ParallelIntStreamSupport.range(1, 1_000_000, pool)
    .filter(PrimesPrint::isPrime)
    .collect(toList())

তবে @ পাবলোম্যাটিয়াসগোমেজ মন্তব্যে উল্লেখ করেছেন যে, সমান্তরাল স্রোতের বিভাজন প্রক্রিয়া সম্পর্কিত কিছু অসুবিধা রয়েছে যা সাধারণ পুলের আকারের উপর নির্ভর করে। দেখুন সমান্তরাল প্রবাহ একটি HashSet থেকে সমান্তরাল চলে না

আমি এই সমাধানটি কেবলমাত্র বিভিন্ন ধরণের কাজের জন্য পৃথক পুল রাখতে ব্যবহার করছি তবে আমি সাধারণ পুলের আকারটি 1 এ সেট করতে পারি না যদিও আমি এটি ব্যবহার না করি।


4

দ্রষ্টব্য: জেডিকে 10 তে একটি স্থির বাস্তবায়ন প্রদর্শিত হবে যা কাস্টম থ্রেড পুলটি প্রত্যাশিত সংখ্যক থ্রেড ব্যবহার করে তা নিশ্চিত করে।

একটি কাস্টম ফোর্কজইনপুলের মধ্যে সমান্তরাল স্ট্রিম এক্সিকিউশনটির সমান্তরালতা মানতে হবে https://bugs.openjdk.java.net/browse/JDK-8190974


1

আমি পুলের আকারটি সামঞ্জস্য করতে নীচে কাস্টম ফোর্কজাইনপুল চেষ্টা করেছি :

private static Set<String> ThreadNameSet = new HashSet<>();
private static Callable<Long> getSum() {
    List<Long> aList = LongStream.rangeClosed(0, 10_000_000).boxed().collect(Collectors.toList());
    return () -> aList.parallelStream()
            .peek((i) -> {
                String threadName = Thread.currentThread().getName();
                ThreadNameSet.add(threadName);
            })
            .reduce(0L, Long::sum);
}

private static void testForkJoinPool() {
    final int parallelism = 10;

    ForkJoinPool forkJoinPool = null;
    Long result = 0L;
    try {
        forkJoinPool = new ForkJoinPool(parallelism);
        result = forkJoinPool.submit(getSum()).get(); //this makes it an overall blocking call

    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    } finally {
        if (forkJoinPool != null) {
            forkJoinPool.shutdown(); //always remember to shutdown the pool
        }
    }
    out.println(result);
    out.println(ThreadNameSet);
}

এখানে আউটপুট বলা হচ্ছে পুলটি ডিফল্ট 4 এর চেয়ে বেশি থ্রেড ব্যবহার করছে ।

50000005000000
[ForkJoinPool-1-worker-8, ForkJoinPool-1-worker-9, ForkJoinPool-1-worker-6, ForkJoinPool-1-worker-11, ForkJoinPool-1-worker-10, ForkJoinPool-1-worker-1, ForkJoinPool-1-worker-15, ForkJoinPool-1-worker-13, ForkJoinPool-1-worker-4, ForkJoinPool-1-worker-2]

তবে বাস্তবে একটি অদ্ভুততা রয়েছে , যখন আমি নীচে ব্যবহার করে একই ফলাফলটি অর্জন করার চেষ্টা করেছি ThreadPoolExecutor:

BlockingDeque blockingDeque = new LinkedBlockingDeque(1000);
ThreadPoolExecutor fixedSizePool = new ThreadPoolExecutor(10, 20, 60, TimeUnit.SECONDS, blockingDeque, new MyThreadFactory("my-thread"));

তবে আমি ব্যর্থ হয়েছি

এটি কেবলমাত্র একটি নতুন থ্রেডে প্যারালাল স্ট্রিম শুরু করবে এবং তারপরে অন্য সব কিছুই ঠিক একই রকম, যা আবার প্রমাণ করে যে তার ছেলের থ্রেড শুরু করতে ফোর্কজাইনপুলটিparallelStream ব্যবহার করবে ।


অন্যান্য নির্বাহকদের অনুমতি না দেওয়ার পিছনে সম্ভাব্য কারণ কী হতে পারে?
ওমজেগো

@ ওমজেগো এটি একটি ভাল প্রশ্ন সম্ভবত আপনি নতুন প্রশ্ন শুরু করতে পারেন এবং আপনার ধারণাগুলি বিস্তারিতভাবে জানাতে আরও বিশদ সরবরাহ করতে পারেন;)
হেরেন

1

অ্যাবাকাসটিল পেতে যান । সমান্তরাল স্ট্রিমের জন্য নির্দিষ্ট করে থ্রেড নম্বরটি। নমুনা কোডটি এখানে:

LongStream.range(4, 1_000_000).parallel(threadNum)...

প্রকাশ : আমি অ্যাবাকাসটিলের বিকাশকারী।


1

আপনি বাস্তবায়ন হ্যাক উপর নির্ভর না চান তাহলে, সবসময় কাস্টম সংগ্রাহক প্রয়োগ করে একই যে একত্রিত হবে অর্জন একটি উপায় mapএবং collectশব্দার্থবিদ্যা ... এবং আপনি ForkJoinPool সীমাবদ্ধ হবে না:

list.stream()
  .collect(parallelToList(i -> fetchFromDb(i), executor))
  .join()

ভাগ্যক্রমে, এটি ইতিমধ্যে এখানে হয়ে গেছে এবং মাভেন সেন্ট্রালে উপলভ্য: http://github.com/pivovarit/parallel-collectors

দাবি অস্বীকার: আমি এটি লিখেছি এবং এর জন্য দায় নেব।


0

আপনি যদি কোনও তৃতীয় পক্ষের লাইব্রেরিটি ব্যবহার করতে আপত্তি করেন না, সাইক্লোপস- রিঅ্যাক্টের সাহায্যে আপনি একই পাইপলাইনের মধ্যে ক্রমিক এবং সমান্তরাল স্ট্রিমগুলি মিশ্রিত করতে পারেন এবং কাস্টম ফোর্কজাইনপুল সরবরাহ করতে পারেন। উদাহরণ স্বরূপ

 ReactiveSeq.range(1, 1_000_000)
            .foldParallel(new ForkJoinPool(10),
                          s->s.filter(i->true)
                              .peek(i->System.out.println("Thread " + Thread.currentThread().getId()))
                              .max(Comparator.naturalOrder()));

বা যদি আমরা অনুক্রমিক স্ট্রিমের মধ্যে প্রক্রিয়া চালিয়ে যেতে চাইতাম

 ReactiveSeq.range(1, 1_000_000)
            .parallel(new ForkJoinPool(10),
                      s->s.filter(i->true)
                          .peek(i->System.out.println("Thread " + Thread.currentThread().getId())))
            .map(this::processSequentially)
            .forEach(System.out::println);

[প্রকাশ আমি সাইক্লোপস-রিএ্যাক্টের প্রধান বিকাশকারী]


0

আপনার যদি কাস্টম থ্রেডপুলের প্রয়োজন না হয় তবে আপনি বরং সমবর্তী কাজের সংখ্যা সীমাবদ্ধ করতে চান তবে আপনি ব্যবহার করতে পারেন:

List<Path> paths = List.of("/path/file1.csv", "/path/file2.csv", "/path/file3.csv").stream().map(e -> Paths.get(e)).collect(toList());
List<List<Path>> partitions = Lists.partition(paths, 4); // Guava method

partitions.forEach(group -> group.parallelStream().forEach(csvFilePath -> {
       // do your processing   
}));

(এটির জন্য জিজ্ঞাসা করা সদৃশ প্রশ্নটি লক করা আছে, সুতরাং দয়া করে আমাকে এখানে রাখুন)


-2

আপনি এই ফর্কজৌইন ওয়ার্কার ট্র্যাডফ্যাক্টিকে বাস্তবায়নের চেষ্টা করতে পারেন এবং এটিকে ফর্ক-জয়েন ক্লাসে ইনজেকশন করতে পারেন।

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();
    }

এটি করতে আপনি ফোর্ক-জয়েন পুলের এই নির্মাতা ব্যবহার করতে পারেন।

দ্রষ্টব্য: - ১. আপনি যদি এটি ব্যবহার করেন তবে বিবেচনা করে নিন যে আপনার নতুন থ্রেড বাস্তবায়নের ভিত্তিতে জেভিএমের সময়সূচী প্রভাবিত হবে, যা সাধারণত কাঁটা-যোগ থ্রেডগুলি বিভিন্ন কোরগুলিতে (একটি গণনীয় থ্রেড হিসাবে গণ্য করা হয়) সিডিউল করে। ২. থ্রেডগুলিতে কাঁটাচামচ দিয়ে যোগদানের মাধ্যমে কার্য নির্ধারণ প্রভাবিত হবে না। ৩. কীভাবে সমান্তরাল স্ট্রিমটি কাঁটাচামচ থেকে থ্রেডগুলি তুলছে তা সত্যই বুঝতে পারেনি (এটিতে সঠিক ডকুমেন্টেশন খুঁজে পাওয়া যায়নি), তাই কোনও ভিন্ন থ্রেডনামিং কারখানা ব্যবহার করে চেষ্টা করুন যাতে নিশ্চিত হয় যে, সমান্তরাল স্ট্রিমের থ্রেডগুলি বেছে নেওয়া হচ্ছে কিনা আপনার সরবরাহ করা কাস্টমথ্রেডফ্যাক্টরি থেকে। ৪. সাধারণ থ্রেডপুল এই কাস্টমথ্রেডফ্যাক্টরিটি ব্যবহার করবে না।


আপনি কি এমন ব্যবহারযোগ্য উদাহরণ প্রদান করতে পারেন যা আপনি যা নির্দিষ্ট করেছেন তা কীভাবে ব্যবহার করতে হবে তা প্রদর্শন করে?
জে মুরে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.