import org.mule.api.MuleContext; import org.mule.api.MuleException; import org.mule.api.context.notification.CustomNotificationListener; import org.mule.api.context.notification.ServerNotification; import org.mule.context.DefaultMuleContextFactory; import org.mule.context.notification.CustomNotification; import org.mule.context.notification.ServerNotificationManager; import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicReference; public class StartStopper { public static void main(String[] args) throws MuleException, InterruptedException { MuleContext ctx = new DefaultMuleContextFactory().createMuleContext(); ctx.start(); ctx.stop(); ctx.dispose(); disposeNotificationManager(ctx.getNotificationManager()); ctx.getWorkManager().dispose(); } private static void disposeNotificationManager(ServerNotificationManager nm) { final AtomicReference state = new AtomicReference("[blocked on eventQueue]"); nm.addListener(new CustomNotificationListener() { public synchronized void onNotification(ServerNotification serverNotification) { transition(state, "[notification sent]", "[blocked in notification - waiting dispose]"); transition(state, "[disposed]", "[done - looping to exit]"); } }); nm.fireNotification(new CustomNotification( "This will block, so before we call eventQue.take() again," + " we can set the disposed flag.", ServerNotification.NO_ACTION_ID )); transition(state, "[blocked on eventQueue]", "[notification sent]"); nm.dispose(); transition(state, "[blocked in notification - waiting dispose]", "[disposed]"); } private static void transition(AtomicReference state, Object expect, Object update) { synchronized (state) { while (!state.compareAndSet(expect, update)) { System.out.printf("Spinning %s -> %s...\n", expect, update); try { state.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } state.notifyAll(); System.out.printf("Transitioned: %s -> %s\n", expect, update); } } }