| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.logging.internal.executors; |
| |
| import java.util.concurrent.ThreadFactory; |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| /** |
| * Threads produced by instances of this class will always |
| * log uncaught exceptions. They will also always be daemon |
| * and have unique names that contain the "baseName" passed |
| * to the constructor. |
| * <p> |
| * What happens each time a thread is created can be customized |
| * using the optional "threadInitializer". |
| * <p> |
| * What happens each time a thread is run can be customized |
| * using the optional "commandWrapper". |
| */ |
| public class LoggingThreadFactory implements ThreadFactory { |
| |
| private final String baseName; |
| private final CommandWrapper commandWrapper; |
| private final ThreadInitializer threadInitializer; |
| private final boolean isDaemon; |
| private final AtomicInteger threadCount = new AtomicInteger(1); |
| |
| public interface ThreadInitializer { |
| void initialize(Thread thread); |
| } |
| |
| public interface CommandWrapper { |
| /** |
| * Invoke the current method passing it a runnable that it can |
| * decide to call when it wants. |
| */ |
| void invoke(Runnable runnable); |
| } |
| |
| /** |
| * Create a factory that produces daemon threads that log uncaught exceptions |
| * |
| * @param baseName the base name will be included in every thread name |
| * @param threadInitializer if not null, will be invoked with the thread each time a thread is |
| * created |
| * @param commandWrapper if not null, will be invoked by each thread created by this factory |
| * @param isDaemon true if threads will be daemons |
| */ |
| public LoggingThreadFactory(String baseName, ThreadInitializer threadInitializer, |
| CommandWrapper commandWrapper, boolean isDaemon) { |
| this.baseName = baseName; |
| this.threadInitializer = threadInitializer; |
| this.commandWrapper = commandWrapper; |
| this.isDaemon = isDaemon; |
| } |
| |
| /** |
| * Create a factory that produces daemon threads that log uncaught exceptions |
| * |
| * @param baseName the base name will be included in every thread name |
| * @param threadInitializer if not null, will be invoked with the thread each time a thread is |
| * created |
| * @param commandWrapper if not null, will be invoked by each thread created by this factory |
| */ |
| public LoggingThreadFactory(String baseName, ThreadInitializer threadInitializer, |
| CommandWrapper commandWrapper) { |
| this(baseName, threadInitializer, commandWrapper, true); |
| } |
| |
| /** |
| * Create a factory that produces daemon threads that log uncaught exceptions |
| * |
| * @param baseName the base name will be included in every thread name |
| */ |
| public LoggingThreadFactory(String baseName) { |
| this(baseName, null, null, true); |
| } |
| |
| /** |
| * Create a factory that produces threads that log uncaught exceptions |
| * |
| * @param baseName the base name will be included in every thread name |
| * @param isDaemon true if threads will be daemons |
| */ |
| public LoggingThreadFactory(String baseName, boolean isDaemon) { |
| this(baseName, null, null, isDaemon); |
| } |
| |
| /** |
| * Create a factory that produces daemon threads that log uncaught exceptions |
| * |
| * @param baseName the base name will be included in every thread name |
| * @param commandWrapper if not null, will be invoked by each thread created by this factory |
| */ |
| public LoggingThreadFactory(String baseName, CommandWrapper commandWrapper) { |
| this(baseName, null, commandWrapper, true); |
| } |
| |
| private String getUniqueName() { |
| return baseName + threadCount.getAndIncrement(); |
| } |
| |
| @Override |
| public Thread newThread(Runnable runnable) { |
| Runnable commandToRun; |
| if (commandWrapper != null) { |
| commandToRun = () -> commandWrapper.invoke(runnable); |
| } else { |
| commandToRun = runnable; |
| } |
| Thread thread = new LoggingThread(getUniqueName(), isDaemon, commandToRun); |
| if (threadInitializer != null) { |
| threadInitializer.initialize(thread); |
| } |
| return thread; |
| } |
| } |