Thread pool thing is pretty simple and fire-and-forget if you want to: Executors.newSingleThreadExecutor().submit(someRunnable);
But it'd be a good idea to save the ExecutorService it returns for later re-use. :) On 19 May 2014 07:22, Ralph Goers <[email protected]> wrote: > I didn't want to manage a pool but to do a fire and forget. > > As for multiple recon figurations, I don't know of the top of my head. I > don't want to introduce locking here but I will see if that is a problem. > > Sent from my iPad > > > On May 19, 2014, at 4:15 AM, Gary Gregory <[email protected]> > wrote: > > > > Does this guarantee that only one concurrent reconfiguration happens at > one any one time? Should it? Use a size 1 thread pool executor with a queue? > > > > Gary > > > > > > -------- Original message -------- > > From: [email protected] > > Date:05/19/2014 00:53 (GMT-05:00) > > To: [email protected] > > Subject: svn commit: r1595741 - in /logging/log4j/log4j2/trunk: > log4j-core/src/main/java/org/apache/logging/log4j/core/config/ > log4j-core/src/test/java/org/apache/logging/log4j/core/ > log4j-core/src/test/java/org/apache/logging/log4j/core/config/ > log4j-core/src/... > > > > Author: rgoers > > Date: Mon May 19 04:53:11 2014 > > New Revision: 1595741 > > > > URL: http://svn.apache.org/r1595741 > > Log: > > LOG4J2-620 - Perform reconfiguration in a separate thread to prevent > deadlocks. > > > > Added: > > > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java > > > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java > > > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java > > > logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml > > Modified: > > > logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java > > > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java > > > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java > > > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java > > logging/log4j/log4j2/trunk/src/changes/changes.xml > > > > Modified: > logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java?rev=1595741&r1=1595740&r2=1595741&view=diff > > > ============================================================================== > > --- > logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java > (original) > > +++ > logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/config/FileConfigurationMonitor.java > Mon May 19 04:53:11 2014 > > @@ -81,7 +81,9 @@ public class FileConfigurationMonitor im > > if (file.lastModified() > lastModified) { > > lastModified = file.lastModified(); > > for (final ConfigurationListener listener : > listeners) { > > - listener.onChange(reconfigurable); > > + Thread thread = new Thread(new > ReconfigurationWorker(listener, reconfigurable)); > > + thread.setDaemon(true); > > + thread.start(); > > } > > } > > } finally { > > @@ -89,4 +91,20 @@ public class FileConfigurationMonitor im > > } > > } > > } > > + > > + private class ReconfigurationWorker implements Runnable { > > + > > + private final ConfigurationListener listener; > > + private final Reconfigurable reconfigurable; > > + > > + public ReconfigurationWorker(ConfigurationListener listener, > Reconfigurable reconfigurable) { > > + this.listener = listener; > > + this.reconfigurable = reconfigurable; > > + } > > + > > + @Override > > + public void run() { > > + listener.onChange(reconfigurable); > > + } > > + } > > } > > > > Modified: > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java?rev=1595741&r1=1595740&r2=1595741&view=diff > > > ============================================================================== > > --- > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java > (original) > > +++ > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/FileConfigTest.java > Mon May 19 04:53:11 2014 > > @@ -81,6 +81,7 @@ public class FileConfigTest { > > for (int i = 0; i < 17; ++i) { > > logger.debug("Reconfigure"); > > } > > + Thread.sleep(100); > > final Configuration cfg = ctx.getConfiguration(); > > assertNotNull("No configuration", cfg); > > assertTrue("Reconfiguration failed", cfg != config); > > > > Modified: > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java?rev=1595741&r1=1595740&r2=1595741&view=diff > > > ============================================================================== > > --- > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java > (original) > > +++ > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java > Mon May 19 04:53:11 2014 > > @@ -238,6 +238,7 @@ public class LoggerTest { > > for (int i = 0; i < 17; ++i) { > > logger.debug("Reconfigure"); > > } > > + Thread.sleep(100); > > final Configuration cfg = ctx.getConfiguration(); > > assertNotNull("No configuration", cfg); > > assertTrue("Reconfiguration failed", cfg != config); > > > > Added: > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java?rev=1595741&view=auto > > > ============================================================================== > > --- > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java > (added) > > +++ > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java > Mon May 19 04:53:11 2014 > > @@ -0,0 +1,127 @@ > > +/* > > + * 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.logging.log4j.core.config; > > + > > +import org.apache.logging.log4j.LogManager; > > +import org.apache.logging.log4j.Logger; > > +import org.apache.logging.log4j.junit.InitialLoggerContext; > > +import org.apache.logging.log4j.message.ThreadDumpMessage; > > +import org.junit.Rule; > > +import org.junit.Test; > > + > > +import java.io.File; > > + > > +import static org.junit.Assert.assertTrue; > > + > > +/** > > + * > > + */ > > +public class ReconfigurationDeadlockTest { > > + > > + @Rule > > + public InitialLoggerContext init = new > InitialLoggerContext("reconfiguration-deadlock.xml"); > > + private static final int THREAD_COUNT = 5; > > + private static final boolean[] finished = new boolean[THREAD_COUNT]; > > + private static LoggerThread[] threads = new > LoggerThread[THREAD_COUNT]; > > + > > + @Test > > + public void testReconfig() throws InterruptedException { > > + > > + Updater updater = new Updater(); > > + for (int i = 0; i < THREAD_COUNT; ++i) { > > + threads[i] = new LoggerThread(i); > > + threads[i].setDaemon(true); > > + } > > + for (int i = 0; i < THREAD_COUNT; ++i) { > > + > > + threads[i].start(); > > + } > > + updater.setDaemon(true); > > + updater.start(); > > + Thread.sleep(100); > > + boolean stillWaiting = true; > > + for (int i = 0; i < 200; ++i) { > > + int index = 0; > > + for (; index < THREAD_COUNT; ++index) { > > + if (!finished[index]) { > > + break; > > + } > > + } > > + if (index == THREAD_COUNT) { > > + stillWaiting = false; > > + break; > > + } > > + Thread.sleep(100); > > + } > > + updater.shutdown = true; > > + if (stillWaiting) { > > + ThreadDumpMessage message = new > ThreadDumpMessage("Waiting"); > > + System.err.print(message.getFormattedMessage()); > > + } > > + for (int i = 0; i < THREAD_COUNT; ++i) { > > + if (threads[i].isAlive()) { > > + threads[i].interrupt(); > > + } > > + } > > + assertTrue("loggerThread didn't finish", stillWaiting == false); > > + > > + } > > + > > + private class LoggerThread extends Thread { > > + > > + private final Logger logger = LogManager.getRootLogger(); > > + private final int index; > > + > > + public LoggerThread(int i) { > > + index = i; > > + } > > + @Override > > + public void run() { > > + int i = 0; > > + try { > > + for (i=0; i < 30; ++i) { > > + logger.error("Thread: " + index + ", Test: " + i++); > > + } > > + } catch (Exception ie) { > > + return; > > + } > > + finished[index] = true; > > + } > > + } > > + > > + private class Updater extends Thread { > > + > > + public volatile boolean shutdown = false; > > + > > + @Override > > + public void run() { > > + while (!shutdown) { > > + try { > > + Thread.sleep(1000); > > + } catch (InterruptedException e) { > > + e.printStackTrace(); > > + } > > + // for running from IDE > > + File file = new > File("target/test-classes/reconfiguration-deadlock.xml"); > > + if (file.exists()) { > > + file.setLastModified(System.currentTimeMillis()); > > + } > > + } > > + } > > + } > > + > > +} > > > > Modified: > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java?rev=1595741&r1=1595740&r2=1595741&view=diff > > > ============================================================================== > > --- > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java > (original) > > +++ > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java > Mon May 19 04:53:11 2014 > > @@ -235,6 +235,7 @@ public class TestConfigurator { > > for (int i = 0; i < 17; ++i) { > > logger.debug("Test message " + i); > > } > > + Thread.sleep(100); > > final Configuration newConfig = ctx.getConfiguration(); > > assertTrue("Configuration not reset", newConfig != config); > > Configurator.shutdown(ctx); > > > > Added: > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java?rev=1595741&view=auto > > > ============================================================================== > > --- > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java > (added) > > +++ > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/SomethingThatUsesLogging.java > Mon May 19 04:53:11 2014 > > @@ -0,0 +1,36 @@ > > +/* > > + * 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.logging.log4j.test; > > + > > +import org.apache.logging.log4j.Level; > > +import org.apache.logging.log4j.LogManager; > > +import org.apache.logging.log4j.Logger; > > +/** > > + * > > + */ > > +public class SomethingThatUsesLogging { > > + > > + private Logger logger; > > + > > + public SomethingThatUsesLogging() { > > + logger = LogManager.getLogger(); > > + } > > + > > + public void doSomething() { > > + logger.isEnabled(Level.DEBUG); > > + } > > +} > > > > Added: > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java?rev=1595741&view=auto > > > ============================================================================== > > --- > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java > (added) > > +++ > logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/UsesLoggingAppender.java > Mon May 19 04:53:11 2014 > > @@ -0,0 +1,69 @@ > > +/* > > + * 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.logging.log4j.test.appender; > > + > > +import org.apache.logging.log4j.core.Filter; > > +import org.apache.logging.log4j.core.Layout; > > +import org.apache.logging.log4j.core.LogEvent; > > +import org.apache.logging.log4j.core.appender.AbstractAppender; > > +import org.apache.logging.log4j.core.config.plugins.Plugin; > > +import org.apache.logging.log4j.core.config.plugins.PluginAttribute; > > +import org.apache.logging.log4j.core.config.plugins.PluginElement; > > +import org.apache.logging.log4j.core.config.plugins.PluginFactory; > > +import org.apache.logging.log4j.test.SomethingThatUsesLogging; > > + > > +/** > > + * > > + */ > > +@Plugin(name = "UsesLoggingAppender", category = "Core", elementType = > "appender", printObject = true) > > +public final class UsesLoggingAppender extends AbstractAppender { > > + > > + private SomethingThatUsesLogging thing; > > + > > + private UsesLoggingAppender(String name, Filter filter, Layout<?> > layout, boolean ignoreExceptions) { > > + super(name, filter, layout, ignoreExceptions); > > + thing = new SomethingThatUsesLogging(); > > + } > > + > > + @PluginFactory > > + public static UsesLoggingAppender > createAppender(@PluginAttribute("name") String name, > > + > @PluginAttribute("ignoreExceptions") String ignore, > > + @PluginElement("Layout") > Layout<?> layout, > > + @PluginElement("Filters") > Filter filter) { > > + > > + boolean ignoreExceptions = Boolean.parseBoolean(ignore); > > + > > + if (name == null) { > > + LOGGER.error("No name provided for MyAppender"); > > + return null; > > + } > > + > > + return new UsesLoggingAppender(name, filter, layout, > ignoreExceptions); > > + } > > + > > + public void append(LogEvent event) { > > + try { > > + for (int i = 0; i < 50; i++) { > > + Thread.sleep(10); > > + thing.doSomething(); > > + } > > + } catch (InterruptedException e) { > > + e.printStackTrace(); > > + } > > + // System.out.print("Log: " + > getLayout().toSerializable(event)); > > + } > > +} > > > > Added: > logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml?rev=1595741&view=auto > > > ============================================================================== > > --- > logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml > (added) > > +++ > logging/log4j/log4j2/trunk/log4j-core/src/test/resources/reconfiguration-deadlock.xml > Mon May 19 04:53:11 2014 > > @@ -0,0 +1,19 @@ > > +<?xml version="1.0" encoding="UTF-8"?> > > +<Configuration status="error" monitorInterval="5"> > > + <Appenders> > > + <UsesLoggingAppender name="myAppender"> > > + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level > %logger{36} - %msg%n" /> > > + </UsesLoggingAppender> > > + <Console name="STDOUT"> > > + <PatternLayout pattern="%m%n"/> > > + </Console> > > + </Appenders> > > + <Loggers> > > + <Logger name="Dump" level="trace" additivity="false"> > > + <AppenderRef ref="STDOUT" /> > > + </Logger> > > + <Root level="ERROR"> > > + <AppenderRef ref="myAppender" /> > > + </Root> > > + </Loggers> > > +</Configuration> > > \ No newline at end of file > > > > Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml > > URL: > http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1595741&r1=1595740&r2=1595741&view=diff > > > ============================================================================== > > --- logging/log4j/log4j2/trunk/src/changes/changes.xml (original) > > +++ logging/log4j/log4j2/trunk/src/changes/changes.xml Mon May 19 > 04:53:11 2014 > > @@ -22,6 +22,9 @@ > > </properties> > > <body> > > <release version="2.0-rc2" date="2014-MM-DD" description="Bug fixes > and enhancements"> > > + <action issue="LOG4J2-620" dev="rgoers" type="fix"> > > + Perform reconfiguration in a separate thread to prevent > deadlocks. > > + </action> > > <action issue="LOG4J2-641" dev="mattsicker" type="update"> > > Override commons-logging dependency version in tests. > > </action> > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > > -- Matt Sicker <[email protected]>
