java开发规则:线程如何被创建

Posted Dreamer who

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java开发规则:线程如何被创建相关的知识,希望对你有一定的参考价值。

目录

1、创建线程请使用线程工厂类

(1)自定义线程工厂

参照java.util.concurrent.Executors类中的线程工厂

(2)建议使用org.apache.commons.lang3.concurrent.BasicThreadFactory

apache lang3 工具包已经提供了一个自定义线程的工厂类,所以,我们放心的使用吧。

2、设置线程的UncaughtExceptionHandler

3、线程资源必须通过线程池来提供,使用线程池避免毫无节制的创建线程释放线程,线程重复利用

4、不要通过java.util.concurrent.Executors工具类来使用线程池,而是通过java.util.concurrent.ThreadPoolExecutor类自定义合理的参数来创建

 

(1) java.util.concurrent.Executors#newFixedThreadPool 创建的线程池是有固定的,但缺点是工作队列是无限的。

(2)java.util.concurrent.Executors#newSingleThreadExecutor()线程池线程虽然是一个,但队列也是无限制的

(3)java.util.concurrent.Executors#newCachedThreadPool() 虽然工作队列是限制的,为0,但线程的个数为Integer.MAX_VALUE,线程数毫无限制。


1、创建线程请使用线程工厂类

(1)自定义线程工厂

参照java.util.concurrent.Executors类中的线程工厂

 /**
     * The default thread factory
     */
    static class DefaultThreadFactory implements ThreadFactory 
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory() 
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        

        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;
        
    

我们很容易自定义线程工厂工具:

 

 static class DefaultThreadFactory implements java.util.concurrent.ThreadFactory 
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory(String namePrefix) 
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            this.namePrefix = namePrefix + "-" + 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;
        
    

指定线程的名字,我们很容在日志中跟踪错误,而且利用jstack命令排查问题很容易。

(2)建议使用org.apache.commons.lang3.concurrent.BasicThreadFactory

apache lang3 工具包已经提供了一个自定义线程的工厂类,所以,我们放心的使用吧。

 BasicThreadFactory basicThreadFactory = new BasicThreadFactory.Builder()
                .namingPattern("sdcuike-thread-%d-")
                .daemon(false)
                .priority(Thread.NORM_PRIORITY).
                        build();

 

2、设置线程的UncaughtExceptionHandler

3、线程资源必须通过线程池来提供,使用线程池避免毫无节制的创建线程释放线程,线程重复利用

4、不要通过java.util.concurrent.Executors工具类来使用线程池,而是通过java.util.concurrent.ThreadPoolExecutor类自定义合理的参数来创建

 

(1) java.util.concurrent.Executors#newFixedThreadPool 创建的线程池是有固定的,但缺点是工作队列是无限的。

 /**
     * Creates a thread pool that reuses a fixed number of threads
     * operating off a shared unbounded queue.  At any point, at most
     * @code nThreads threads will be active processing tasks.
     * If additional tasks are submitted when all threads are active,
     * they will wait in the queue until a thread is available.
     * If any thread terminates due to a failure during execution
     * prior to shutdown, a new one will take its place if needed to
     * execute subsequent tasks.  The threads in the pool will exist
     * until it is explicitly @link ExecutorService#shutdown shutdown.
     *
     * @param nThreads the number of threads in the pool
     * @return the newly created thread pool
     * @throws IllegalArgumentException if @code nThreads <= 0
     */
    public static ExecutorService newFixedThreadPool(int nThreads) 
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    
 /**
     * Creates a thread pool that reuses a fixed number of threads
     * operating off a shared unbounded queue, using the provided
     * ThreadFactory to create new threads when needed.  At any point,
     * at most @code nThreads threads will be active processing
     * tasks.  If additional tasks are submitted when all threads are
     * active, they will wait in the queue until a thread is
     * available.  If any thread terminates due to a failure during
     * execution prior to shutdown, a new one will take its place if
     * needed to execute subsequent tasks.  The threads in the pool will
     * exist until it is explicitly @link ExecutorService#shutdown
     * shutdown.
     *
     * @param nThreads the number of threads in the pool
     * @param threadFactory the factory to use when creating new threads
     * @return the newly created thread pool
     * @throws NullPointerException if threadFactory is null
     * @throws IllegalArgumentException if @code nThreads <= 0
     */
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) 
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
    

(2)java.util.concurrent.Executors#newSingleThreadExecutor()线程池线程虽然是一个,但队列也是无限制的

 /**
     * Creates an Executor that uses a single worker thread operating
     * off an unbounded queue. (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.)  Tasks are guaranteed to execute
     * sequentially, and no more than one task will be active at any
     * given time. Unlike the otherwise equivalent
     * @code newFixedThreadPool(1) the returned executor is
     * guaranteed not to be reconfigurable to use additional threads.
     *
     * @return the newly created single-threaded Executor
     */
    public static ExecutorService newSingleThreadExecutor() 
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    

(3)java.util.concurrent.Executors#newCachedThreadPool() 虽然工作队列是限制的,为0,但线程的个数为Integer.MAX_VALUE,线程数毫无限制。

 /**
     * 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 @code execute 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. Note that pools with similar
     * properties but different details (for example, timeout parameters)
     * may be created using @link ThreadPoolExecutor constructors.
     *
     * @return the newly created thread pool
     */
    public static ExecutorService newCachedThreadPool() 
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    

 

以上是关于java开发规则:线程如何被创建的主要内容,如果未能解决你的问题,请参考以下文章

阿里巴巴Java开发规范手册

Java开发如何创建一个线程?

Java线程面试题

Java线程面试题

Java线程面试题

Java线程面试题 Top 50