All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.paypal.cascade.common.concurrent.NamedThreadFactory.scala Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2013-2014 PayPal
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.paypal.cascade.common.concurrent

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

/**
 * Provide a method to get DefaultThreadFactory instances with a specified thread name prefix.
 * This should be used to make debugging easier.
 *
 * The root thread is the top-most thread of the current JVM. A method is provided here to obtain a factor that
 * creates daemon children directly under that root thread.
 *
 * Refer to documentation on [[java.lang.Thread]] for distinctions between daemon/non-daemon threads.
 * Short version: daemon threads die immediately when their parent dies; non-daemon threads are allowed to finish.
 */
trait NamedThreadFactory {

  /**
   * Returns a new named non-daemon thread factory at normal thread priority.
   * @param prefix the name prefix for threads of this factory
   * @return a new ThreadFactory
   */
  def namedThreadFactory(prefix: String): ThreadFactory = {
    newThreadFactory(defaultThreadGroup(), prefix, false, Thread.NORM_PRIORITY)
  }

  /**
   * Returns a new named daemon thread factory at normal thread priority.
   * @param prefix the name prefix for threads of this factory
   * @return a new ThreadFactory
   */
  def namedDaemonThreadFactory(prefix: String): ThreadFactory = {
    newThreadFactory(defaultThreadGroup(), prefix, true, Thread.NORM_PRIORITY)
  }

  /**
   * Returns a new named daemon thread factory, for daemon threads under the root thread, at normal thread priority.
   * @param prefix the name prefix for threads of this factory
   * @return a new ThreadFactory
   */
  def namedDaemonRootThreadFactory(prefix: String): ThreadFactory = {
    newThreadFactory(rootThreadGroup(), prefix, true, Thread.NORM_PRIORITY)
  }

  private def newThreadFactory(group: ThreadGroup, prefix: String, isDaemon: Boolean, priority: Int) = new ThreadFactory {
    //DefaultThreadFactory impl (converted to scala) with a custom prefix
    //e.g. http://fuseyism.com/classpath/doc/java/util/concurrent/Executors-source.html
    val threadNumber = new AtomicInteger(1)

    override def newThread(r: Runnable): Thread = {
      val t = new Thread(group, r, s"$prefix-${threadNumber.getAndIncrement}", 0)
      t.setDaemon(isDaemon)
      t.setPriority(priority)
      t
    }

  }

  private def defaultThreadGroup(): ThreadGroup = Option(System.getSecurityManager) match {
    case Some(sm) => sm.getThreadGroup
    case None => Thread.currentThread.getThreadGroup
  }

  /**
   * Returns the root thread group.
   * @return the root thread group
   */
  private def rootThreadGroup(): ThreadGroup = {
    def getRootThreadGroup(node: ThreadGroup): ThreadGroup = {
      Option(node.getParent).map(getRootThreadGroup).getOrElse(node)
    }
    getRootThreadGroup(Thread.currentThread.getThreadGroup)
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy