io.neba.core.blueprint.EventhandlingBarrier Maven / Gradle / Ivy
/**
* Copyright 2013 the original author or authors.
*
* 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 io.neba.core.blueprint;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
/**
* Contains a global {@link Lock} on which the event handlers changing the
* framework state (e.g. registered {@link io.neba.api.annotations.ResourceModel models} or self tests)
* may synchronize to prevent undefined state due to concurrent modifications.
* {@link #begin()} must always be followed by {@link #end()}, i.e. {@link #end()} should
* be included in a finally block like so:
*
*
* EventHandling.begin();
* try {
* // do something
* } finally {
* EventHandling.end();
* }
*
*
* @author Olaf Otto
*/
public class EventhandlingBarrier {
private static final Lock LOCK = new ReentrantLock();
/**
* Tries to obtain a lock. Waits up to ten minutes for the locking to succeed, or fails
* with an {@link IllegalStateException}. Rationale: Waiting indefinitely for a lock is bad practice,
* since it enables deadlocks.
*/
public static void begin() {
boolean locked;
try {
locked = LOCK.tryLock(10, MINUTES);
} catch (InterruptedException e) {
throw new IllegalStateException("Interrupted while attempting to obtain the event handling lock.", e);
}
if (!locked) {
throw new IllegalStateException("Unable to obtain the event handling lock within ten minutes, giving up. " +
"This may indicate a deadlocked process. Please create " +
"a thread dump and consult the error.log.");
}
}
/**
* This method tries to obtain a lock and return false
if this
* does not succeed. This method can be used if the
* execution of the synchronous code is optional and may otherwise
* result in a deadlock.
*
* @see Lock#tryLock(long, java.util.concurrent.TimeUnit)
*/
public static boolean tryBegin() {
try {
return LOCK.tryLock(10, SECONDS);
} catch (InterruptedException e) {
return false;
}
}
/**
* @see #begin()
*/
public static void end() {
LOCK.unlock();
}
private EventhandlingBarrier() {}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy