এক্সিকিউটর সার্ভিসের নামকরণ থ্রেড এবং থ্রেড-পুল


227

ধরা যাক আমার কাছে এমন একটি অ্যাপ্লিকেশন রয়েছে যা Executorফ্রেমওয়ার্কটি যেমন ব্যবহার করে

Executors.newSingleThreadExecutor().submit(new Runnable(){
    @Override
    public void run(){
        // do stuff
    }
}

যখন আমি ডিবাগার এই অ্যাপ্লিকেশন চালানোর, একটি থ্রেড নিম্নলিখিত (ডিফল্ট) নাম দিয়ে তৈরি হয়: Thread[pool-1-thread-1]। আপনি দেখতে পাচ্ছেন, এটি মারাত্মকভাবে কার্যকর নয় এবং যতদূর আমি বলতে পারি Executorফ্রেমওয়ার্কটি তৈরি থ্রেড বা থ্রেড-পুলের নামকরণের কোনও সহজ উপায় সরবরাহ করে না।

সুতরাং, কেউ কীভাবে থ্রেড / থ্রেড-পুলের নাম সরবরাহ করবে? উদাহরণস্বরূপ Thread[FooPool-FooThread],।

উত্তর:


117

আপনি একটি সরবরাহ করতে ThreadFactoryপারে newSingleThreadScheduledExecutor(ThreadFactory threadFactory)। কারখানাটি থ্রেড তৈরির জন্য দায়বদ্ধ হবে এবং সেগুলির নাম রাখতে সক্ষম হবে।

জাভাদোকের উদ্ধৃতি দিতে :

নতুন থ্রেড তৈরি করা হচ্ছে

নতুন থ্রেড ব্যবহার করে তৈরি করা হয় a ThreadFactory। অন্যথায় নির্দিষ্ট না করা থাকলে, একটি Executors.defaultThreadFactory()ব্যবহার করা হয়, যা সকলের জন্য একই থ্রেড তৈরি করে ThreadGroupএবং একই NORM_PRIORITYঅগ্রাধিকার এবং নন-ডেমন স্থিতি দিয়ে। অন্যরকম সরবরাহ করে ThreadFactoryআপনি থ্রেডের নাম, থ্রেড গ্রুপ, অগ্রাধিকার, ডেমোন স্ট্যাটাস ইত্যাদি পরিবর্তন করতে পারেন, যদি ThreadFactoryশূন্য থেকে ফিরে জিজ্ঞাসা করে কোনও থ্রেড তৈরি করতে ব্যর্থ হয় newThreadতবে এক্সিকিউটার চালিয়ে যাবে, তবে কোনও কাজ সম্পাদন করতে সক্ষম নাও হতে পারে


282

পেয়ারা প্রায় সবসময় আপনার প্রয়োজন হয়

ThreadFactory namedThreadFactory = 
  new ThreadFactoryBuilder().setNameFormat("my-sad-thread-%d").build()

এবং এটি আপনার কাছে ছেড়ে দিন ExecutorService


3
সেটা চমৎকার!
মার্টিন ভ্যাসেটিকা

25
এটা দুঃখের! :-(
এক্সিক

"পেয়ারা" কোথায় পাবেন তা আমি নিশ্চিত নই। গুগলের পেয়ারাতে প্রচুর অংশ রয়েছে এবং একই নামে কয়েক ডজন লাইব্রেরি রয়েছে। আমি ধরে নিচ্ছি আপনার অর্থ অনুসন্ধান.মেন.আর.এনগ.আর.আর্টিফ্যাক্ট / কমপিউএল.গাভা / গুয়াভা / 29.0-jre/… । এটা কি সঠিক? আপনি যে লিঙ্কটি সরবরাহ করেন তা এটি গুগলের থেকে বোঝা যায়, তবে গুগলের "পেয়ারা" নামক মাভেন / সোন্যাটাইপে প্রায় অর্ধ ডজন শিল্পকলা রয়েছে।
জেসন

@ জেসন - আপনি যদি একটি তুচ্ছ জাভা প্রকল্প লিখছেন তবে আপনার সম্ভবত ইতিমধ্যে নির্ভরতা হিসাবে পেয়ারা থাকা উচিত। এবং এটি এখানে: github.com/google/guava
প্যাথিক্রিট

@ পাথিক্রিত, ধন্যবাদ! আমি মনে করি আমাকে আরও পেয়ারার উপর পড়াশোনা করা দরকার :-)
জেসন

95

আপনি নিজের থ্রেড কারখানাটি সরবরাহ করার চেষ্টা করতে পারেন যা উপযুক্ত নাম দিয়ে থ্রেড তৈরি করবে। একটি উদাহরণ এখানে:

class YourThreadFactory implements ThreadFactory {
   public Thread newThread(Runnable r) {
     return new Thread(r, "Your name");
   }
 }

Executors.newSingleThreadExecutor(new YourThreadFactory()).submit(someRunnable);

58

থ্রেডটি কার্যকর হওয়ার পরে আপনি নিজের থ্রেডের নামও পরে পরিবর্তন করতে পারবেন:

Thread.currentThread().setName("FooName");

এটি আগ্রহী হতে পারে যদি উদাহরণস্বরূপ আপনি একই ধরণের থ্রেডফ্যাক্টরি বিভিন্ন ধরণের কাজের জন্য ব্যবহার করছেন।


7
এটি দুর্দান্তভাবে কাজ করেছে কারণ ফ্লোরিয়ানটি বর্ণিত হিসাবে আমার কাছে বিভিন্ন ধরণের থ্রেড রয়েছে এবং কেবল নামের জন্য একাধিক থ্রেডফ্যাক্টরি অবজেক্ট তৈরি করতে চাইনি। আমি থ্রেড.কন্ট্রেনথ্রেড ()। সেটনাম ("FooName") বলেছি; প্রতিটি রান () পদ্ধতিতে প্রথম লাইন হিসাবে।
রবিন জিম্মার্মান

5
যখন ব্যর্থতা আচরণ ডক্স বর্ণিত ঘটে এই সঙ্গে এক ছোটখাট সমস্যা হল: (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)। যদি এক্সিকিউটর সার্ভিস থ্রেডটি প্রতিস্থাপন করে তবে এটি থ্রেডফ্যাক্ট্রি দ্বারা নামকরণ করা হবে। তারপরে আবার, নামটি অদৃশ্য হয়ে যাওয়ার সময় ডিবাগিং দরকারী সূচক হতে পারে।
সেথ্রো

কেবল দুর্দান্ত! ধন্যবাদ.
এজেগেস করুন

1
অন্য উত্তরটি যেমন বলে, নাম সেট করার জন্য এটি একটি দ্রুত এবং নোংরা পদ্ধতি এবং আপনি যদি একাধিক থ্রেড দিয়ে এটি করেন তবে সমস্তেরই একই নাম থাকবে !!
তানো

প্রস্থান করার পরে থ্রেডের নামটি আবার মূলতে সেট করতে পারে, কারণ এটি বিভিন্ন সম্পর্কযুক্ত কোনও কাজ করে থাকলেও নামটি ধরে রাখতে পারে।
ডাস্টিন কে

51

BasicThreadFactoryApache Commons-ল্যাঙ থেকে নামকরণ আচরণ প্রদান দরকারী। বেনামে অভ্যন্তরীণ শ্রেণি লেখার পরিবর্তে আপনি বিল্ডারটি নিজের পছন্দমতো থ্রেডগুলির নাম রাখতে পারেন to জাভাডোকস থেকে উদাহরণ এখানে:

 // Create a factory that produces daemon threads with a naming pattern and
 // a priority
 BasicThreadFactory factory = new BasicThreadFactory.Builder()
     .namingPattern("workerthread-%d")
     .daemon(true)
     .priority(Thread.MAX_PRIORITY)
     .build();
 // Create an executor service for single-threaded execution
 ExecutorService exec = Executors.newSingleThreadExecutor(factory);

30

আপনি যদি স্প্রিং ব্যবহার করছেন তবে এমন CustomizableThreadFactoryএকটি বিষয় রয়েছে যার জন্য আপনি থ্রেড নামের উপসর্গটি সেট করতে পারেন।

উদাহরণ:

ExecutorService alphaExecutor =
    Executors.newFixedThreadPool(10, new CustomizableThreadFactory("alpha-"));

বিকল্পভাবে, আপনি ExecutorServiceএকটি স্প্রিং বিন হিসাবে ThreadPoolExecutorFactoryBeanএটি ব্যবহার করে তৈরি করতে পারেন - তারপরে থ্রেডগুলি সমস্ত beanName-উপসর্গের সাথে নামকরণ করা হবে ।

@Bean
public ThreadPoolExecutorFactoryBean myExecutor() {
    ThreadPoolExecutorFactoryBean executorFactoryBean = new ThreadPoolExecutorFactoryBean();
    // configuration of your choice
    return executorFactoryBean;
}

উপরের উদাহরণে, থ্রেডগুলির myExecutor-উপসর্গ দিয়ে নামকরণ করা হবে । আপনি কারখানার শিমের উপর "myPool-"সেট executorFactoryBean.setThreadNamePrefix("myPool-")করে আলাদাভাবে আলাদা মান (উদা। ) এর উপসর্গটি সুস্পষ্টভাবে সেট করতে পারেন ।


কাস্টমাইজডথ্রেডফ্যাক্টরি খুঁজে পাচ্ছেন না? আমি jdk 1.7 ব্যবহার করছি। কোন ধারণা আমি এখানে কি অনুপস্থিত?
কামরান শহীদ

@ কামরানশাহিদ এটি একটি স্প্রিং ফ্রেমওয়ার্ক ক্লাস, এটির জন্য আপনার অবশ্যই বসন্তটি ব্যবহার করতে হবে
অ্যাডাম মিশালিক

20

ওরাকল সহ এটির জন্য একটি মুক্ত আরএফই রয়েছে । ওরাকল কর্মচারীর মন্তব্য থেকে মনে হয় তারা বিষয়টি বুঝতে পারে না এবং ঠিক করে না। এটি জেডিকে সমর্থন করার জন্য মরে যাওয়া সহজ বিষয়গুলির মধ্যে একটি (পিছনে সামঞ্জস্যতা ভঙ্গ না করে) তাই আরএফই ভুল বোঝাবুঝি হয়ে যায় এটা এক ধরণের লজ্জার বিষয়।

নির্দেশিত হিসাবে আপনার নিজের থ্রেডফ্যাক্টরি বাস্তবায়ন করা উচিত । আপনি যদি এই উদ্দেশ্যে কেবল পেয়ারা বা অ্যাপাচি কমন্সে টানতে না চান তবে আমি এখানে এমন একটি ThreadFactoryবাস্তবায়ন সরবরাহ করব যা আপনি ব্যবহার করতে পারেন। "পুল" ব্যতীত অন্য কোনও থ্রেড নামের উপসর্গটি সেট করার ক্ষমতা ব্যতীত আপনি জেডিকে থেকে যা পান তার ঠিক এটি মিল।

package org.demo.concurrency;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * ThreadFactory with the ability to set the thread name prefix. 
 * This class is exactly similar to 
 * {@link java.util.concurrent.Executors#defaultThreadFactory()}
 * from JDK8, except for the thread naming feature.
 *
 * <p>
 * The factory creates threads that have names on the form
 * <i>prefix-N-thread-M</i>, where <i>prefix</i>
 * is a string provided in the constructor, <i>N</i> is the sequence number of
 * this factory, and <i>M</i> is the sequence number of the thread created 
 * by this factory.
 */
public class ThreadFactoryWithNamePrefix implements ThreadFactory {

    // Note:  The source code for this class was based entirely on 
    // Executors.DefaultThreadFactory class from the JDK8 source.
    // The only change made is the ability to configure the thread
    // name prefix.


    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    /**
     * Creates a new ThreadFactory where threads are created with a name prefix
     * of <code>prefix</code>.
     *
     * @param prefix Thread name prefix. Never use a value of "pool" as in that
     *      case you might as well have used
     *      {@link java.util.concurrent.Executors#defaultThreadFactory()}.
     */
    public ThreadFactoryWithNamePrefix(String prefix) {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup()
                : Thread.currentThread().getThreadGroup();
        namePrefix = prefix + "-"
                + poolNumber.getAndIncrement()
                + "-thread-";
    }


    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                namePrefix + threadNumber.getAndIncrement(),
                0);
        if (t.isDaemon()) {
            t.setDaemon(false);
        }
        if (t.getPriority() != Thread.NORM_PRIORITY) {
            t.setPriority(Thread.NORM_PRIORITY);
        }
        return t;
    }
}

আপনি যখন এটি ব্যবহার করতে চান আপনি সহজভাবে এই সুযোগটি গ্রহণ করবেন যে সমস্ত Executorsপদ্ধতি আপনাকে নিজের সরবরাহ করতে দেয় ThreadFactory

এই

    Executors.newSingleThreadExecutor();

একটি এক্সিকিউটার সার্ভিস দেবে যেখানে থ্রেডগুলির নাম দেওয়া হয়েছে pool-N-thread-Mতবে ব্যবহার করে

    Executors.newSingleThreadExecutor(new ThreadFactoryWithNamePrefix("primecalc"));

থ্রেডের নাম দেওয়া হয়েছে এমন একটি এক্সিকিউটার সার্ভিস পাবেন primecalc-N-thread-M। ভাল খবর!


আপনি আপনার শেষ স্নিপেটে একটি বন্ধনী প্রথম বন্ধনী মিস করেছেন
21.19

সোনারলিন্ট / কিউব তার ThreadGroupপক্ষে ব্যবহার না করা পছন্দ করে এমন একটি দ্রুত নোট ThreadPoolExecutor
ছকড়া

8
private class TaskThreadFactory implements ThreadFactory
{

    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r, "TASK_EXECUTION_THREAD");

        return t;
    }

}

থ্রেডফ্যাক্টরিকে একজন এক্সিকিউটার সার্ভিসে পাস করুন এবং আপনি যেতে ভাল


8

একটি দ্রুত এবং নোংরা উপায় পদ্ধতিতে ব্যবহার Thread.currentThread().setName(myName);করা হয় run()


7

থ্রেডফ্যাক্টরি প্রসারিত করুন

public interface ThreadFactory

এমন একটি বস্তু যা চাহিদা অনুযায়ী নতুন থ্রেড তৈরি করে। থ্রেড ফ্যাক্টরিগুলি ব্যবহার করে নতুন থ্রেডের কলগুলির হার্ডওয়ারিং সরিয়ে দেয়, অ্যাপ্লিকেশনগুলিকে বিশেষ থ্রেড সাবক্লাস, অগ্রাধিকার ইত্যাদি ব্যবহারের সক্ষম করে etc.

Thread newThread(Runnable r)

একটি নতুন থ্রেড তৈরি করে। বাস্তবায়নগুলি অগ্রাধিকার, নাম, ডেমোন স্থিতি, থ্রেডগ্রুপ ইত্যাদি শুরু করতে পারে may

কোডের উদাহরণ:

import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

import java.util.concurrent.ThreadPoolExecutor.DiscardPolicy;

class SimpleThreadFactory implements ThreadFactory {
   String name;
   AtomicInteger threadNo = new AtomicInteger(0);

   public SimpleThreadFactory (String name){
       this.name = name;
   }
   public Thread newThread(Runnable r) {
     String threadName = name+":"+threadNo.incrementAndGet();
     System.out.println("threadName:"+threadName);
     return new Thread(r,threadName );
   }
   public static void main(String args[]){
        SimpleThreadFactory factory = new SimpleThreadFactory("Factory Thread");
        ThreadPoolExecutor executor= new ThreadPoolExecutor(1,1,60,
                    TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1),new ThreadPoolExecutor.DiscardPolicy());


        final ExecutorService executorService = Executors.newFixedThreadPool(5,factory);

        for ( int i=0; i < 100; i++){
            executorService.submit(new Runnable(){
                 public void run(){
                    System.out.println("Thread Name in Runnable:"+Thread.currentThread().getName());
                 }
            });
        }
        executorService.shutdown();
    }
 }

আউটপুট:

java SimpleThreadFactory

thread no:1
thread no:2
Thread Name in Runnable:Factory Thread:1
Thread Name in Runnable:Factory Thread:2
thread no:3
thread no:4
Thread Name in Runnable:Factory Thread:3
Thread Name in Runnable:Factory Thread:4
thread no:5
Thread Name in Runnable:Factory Thread:5

.... ইত্যাদি


1
আপনার থ্রেড কাউন্টার থ্রেড-নিরাপদ নয়: আপনার উচিত হবে অ্যাটমিকআইন্টিজার।
পিনো

পরামর্শের জন্য ধন্যবাদ। আমি আপনার পরামর্শ অন্তর্ভুক্ত করেছি।
রবীন্দ্র বাবু

5

অন্যান্য উত্তর যেমন ইতিমধ্যে বলেছে, আপনি java.util.concurrent.ThreadFactoryইন্টারফেসের নিজস্ব প্রয়োগ তৈরি করতে এবং ব্যবহার করতে পারেন (কোনও বাহ্যিক গ্রন্থাগারের প্রয়োজন নেই)। আমি নীচে আমার কোডটি আটকে দিচ্ছি কারণ এটি পূর্ববর্তী উত্তরগুলির চেয়ে আলাদা কারণ এটি String.formatপদ্ধতিটি ব্যবহার করে এবং কনস্ট্রাক্টর আর্গুমেন্ট হিসাবে থ্রেডগুলির জন্য একটি বেস নাম নেয়:

import java.util.concurrent.ThreadFactory;

public class NameableThreadFactory implements ThreadFactory{
    private int threadsNum;
    private final String namePattern;

    public NameableThreadFactory(String baseName){
        namePattern = baseName + "-%d";
    }

    @Override
    public Thread newThread(Runnable runnable){
        threadsNum++;
        return new Thread(runnable, String.format(namePattern, threadsNum));
    }    
}

এবং এটি ব্যবহারের একটি উদাহরণ:

ThreadFactory  threadFactory = new NameableThreadFactory("listenerThread");        
final ExecutorService executorService = Executors.newFixedThreadPool(5, threadFactory);

সম্পাদনা করুন : আমার ThreadFactoryবাস্তবায়ন থ্রেড-নিরাপদ করে তুলেছে , এটি নির্দেশ করার জন্য @ মেশেরন্যাকভকে ধন্যবাদ ।
যদিও ThreadFactoryডকুমেন্টেশনের কোথাও বলা হয়নি যে এর বাস্তবায়নগুলি অবশ্যই থ্রেড-নিরাপদ হওয়া উচিত, DefaultThreadFactoryথ্রেড-নিরাপদ এটি একটি বড় ইঙ্গিত:

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class NameableThreadFactory implements ThreadFactory{
    private final AtomicInteger threadsNum = new AtomicInteger();

    private final String namePattern;

    public NameableThreadFactory(String baseName){
        namePattern = baseName + "-%d";
    }

    @Override
    public Thread newThread(Runnable runnable){
        return new Thread(runnable, String.format(namePattern, threadsNum.addAndGet(1)));
    }    
}

1
আপনার থ্রেড কাউন্টার (থ্রেডনম) থ্রেডসফ নয়, আপনার অ্যাটমিক ইন্টিজার ব্যবহার করা উচিত।
mchernyakov

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

4

আমি বিদ্যমান কারখানার সাজসজ্জার জন্য যে ঘরোয়া উত্সাহিত মূল জাভা সমাধানটি ব্যবহার করি:

public class ThreadFactoryNameDecorator implements ThreadFactory {
    private final ThreadFactory defaultThreadFactory;
    private final String suffix;

    public ThreadFactoryNameDecorator(String suffix) {
        this(Executors.defaultThreadFactory(), suffix);
    }

    public ThreadFactoryNameDecorator(ThreadFactory threadFactory, String suffix) {
        this.defaultThreadFactory = threadFactory;
        this.suffix = suffix;
    }

    @Override
    public Thread newThread(Runnable task) {
        Thread thread = defaultThreadFactory.newThread(task);
        thread.setName(thread.getName() + "-" + suffix);
        return thread;
    }
}

কর্মে:

Executors.newSingleThreadExecutor(new ThreadFactoryNameDecorator("foo"));

3
Executors.newSingleThreadExecutor(r -> new Thread(r, "someName")).submit(getJob());

Runnable getJob() {
        return () -> {
            // your job
        };
}

3

আপনি থ্রেডফ্যাক্টরীর নিজস্ব প্রয়োগটি লিখতে পারেন উদাহরণস্বরূপ কিছু বিদ্যমান বাস্তবায়ন (ডিফল্ট থ্রেডফ্যাক্টির মতো) ব্যবহার করে এবং শেষে নামটি পরিবর্তন করতে পারেন।

থ্রেডফ্যাক্টরি বাস্তবায়নের উদাহরণ:

class ThreadFactoryWithCustomName implements ThreadFactory {
    private final ThreadFactory threadFactory;
    private final String name;

    public ThreadFactoryWithCustomName(final ThreadFactory threadFactory, final String name) {
        this.threadFactory = threadFactory;
        this.name = name;
    }

    @Override
    public Thread newThread(final Runnable r) {
        final Thread thread = threadFactory.newThread(r);
        thread.setName(name);
        return thread;
    }
}

এবং ব্যবহার:

Executors.newSingleThreadExecutor(new ThreadFactoryWithCustomName(
        Executors.defaultThreadFactory(),
        "customName")
    );

3

আমি নীচের মতো একই ব্যবহার করতে চাই ( guavaগ্রন্থাগারের প্রয়োজন ):

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("SO-POOL-%d").build();
ExecutorService executorService = Executors.newFixedThreadPool(5,namedThreadFactory);

1
ThreadFactoryBuilderগুগল পেয়ারা লাইব্রেরি থেকে এটি লক্ষণীয় ।
ক্রেগ ওটিস

3

থ্রেড ফ্যাক্টরি হিসাবে ল্যাম্বডা ব্যবহার করা আমার পক্ষে সবচেয়ে সহজ মনে হয় যদি আপনি কেবল একটি একক থ্রেড এক্সিকিউটারের নাম পরিবর্তন করতে চান।

Executors.newSingleThreadExecutor(runnable -> new Thread(runnable, "Your name"));

এটি দুটি থ্রেড তৈরি করে। একজনের নাম "আপনার নাম" এবং অন্যটি "পুল-এন-থ্রেড-এম"
21

@ সিস্টেমসপ্ল্যানেট না, এটি হয় না। একটি নূন্যতম উদাহরণ থেকে একটি থ্রেড ডাম্প নেওয়া যা নির্বাহকটি একটি থ্রেড চালাতে ব্যবহার করে যা নীচে নীচের থ্রেডগুলি দেখায়:main@1, Finalizer@667, Reference Handler@668, Your name@665, Signal Dispatcher@666
ক্যামডাব্লু

হুম, আমি যখন চেষ্টা করেছিলাম তখন তা করেছে। এটি উপলব্ধি করে যে এটি যেহেতু আপনি এটি একটি নতুন রান্নেবল () পাস করলে এটি আপনার জন্য একটি থ্রেড তৈরি করে এবং আপনি নিজেই একটি থ্রেড তৈরি করছেন।
সিস্টেমে প্ল্যানেট

আমি প্রত্যাশা করি যে আপনি এর পরিবর্তে একটি থ্রেডপুলএক্সিকিউটর ব্যবহার করেছেন বা অন্য কোনও উদ্দেশ্যে একটি চালাচ্ছেন। এই কোডটি "পুল-এন-থ্রেড-এম" থ্রেড তৈরি করবে না। এছাড়াও, আমি বিশ্বাস করি না যে এটি যে তা করবে তা বোঝায় না। আপনার বক্তব্য "যদি আপনি এটি একটি নতুন রানযোগ্য (পাস) করে দেন তবে এটি আপনার জন্য একটি থ্রেড তৈরি করে" সঠিক নয়। এটি একটি থ্রেড তৈরি করতে চালিত হয় এবং এটি একবার ব্যবহার করে কারণ এটি একক থ্রেড নির্বাহক। শুধুমাত্র 1 থ্রেড তৈরি করা হয়।
ক্যামডাব্লু

2

এটি আমার কাস্টমাইজড কারখানাটি থ্রেড ডাম্প বিশ্লেষকদের জন্য অনুকূলিতকরণের নাম সরবরাহ করে providing সাধারণত আমি কেবল tf=nullজেভিএম ডিফল্ট থ্রেড কারখানার পুনরায় ব্যবহার করতে পারি । এই ওয়েবসাইটে আরও উন্নত থ্রেড কারখানা রয়েছে।

public class SimpleThreadFactory implements ThreadFactory {
    private ThreadFactory tf;
    private String nameSuffix;

    public SimpleThreadFactory (ThreadFactory tf, String nameSuffix) {
        this.tf = tf!=null ? tf : Executors.defaultThreadFactory();
        this.nameSuffix = nameSuffix; 
    }

    @Override public Thread newThread(Runnable task) {
        // default "pool-1-thread-1" to "pool-1-thread-1-myapp-MagicTask"
        Thread thread=tf.newThread(task);
        thread.setName(thread.getName()+"-"+nameSuffix);
        return thread;
    }
}

- - - - - 

ExecutorService es = Executors.newFixedThreadPool(4, new SimpleThreadFactory(null, "myapp-MagicTask") );

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

    ThreadMXBean mxBean=ManagementFactory.getThreadMXBean();
    long[] tids = mxBean.getAllThreadIds();
    System.out.println("------------");
    System.out.println("ThreadCount="+tids.length);
    for(long tid : tids) {
        ThreadInfo mxInfo=mxBean.getThreadInfo(tid);
        if (mxInfo==null) {
            System.out.printf("%d %s\n", tid, "Thread not found");
        } else {
            System.out.printf("%d %s, state=%s, suspended=%d, lockowner=%d %s\n"
                    , mxInfo.getThreadId(), mxInfo.getThreadName()
                    , mxInfo.getThreadState().toString()
                    , mxInfo.isSuspended()?1:0
                    , mxInfo.getLockOwnerId(), mxInfo.getLockOwnerName()
            );
        }
    }

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