--- old/src/java.management/share/classes/sun/management/NotificationEmitterSupport.java 2018-03-20 00:33:08.405183557 -0700 +++ new/src/java.management/share/classes/sun/management/NotificationEmitterSupport.java 2018-03-20 00:33:08.093155211 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,14 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import jdk.internal.misc.InnocuousThread; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.concurrent.ThreadFactory; + + /** * Abstract helper class for notification emitter support. */ @@ -149,10 +157,9 @@ for (int i = 0; i < size; i++) { ListenerInfo li = currentList.get(i); - if (li.filter == null - || li.filter.isNotificationEnabled(notification)) { + if (li.filter == null || li.filter.isNotificationEnabled(notification)) { try { - li.listener.handleNotification(notification, li.handback); + NotificationThread.executor.execute(() -> li.handle(notification, li.handback)); } catch (Exception e) { e.printStackTrace(); throw new AssertionError("Error in invoking listener"); @@ -166,7 +173,6 @@ return !listenerList.isEmpty(); } } - private class ListenerInfo { public NotificationListener listener; NotificationFilter filter; @@ -179,8 +185,37 @@ this.filter = filter; this.handback = handback; } + public void handle(Notification notif, Object handback) { + try { + listener.handleNotification(notif, handback); + } catch (Exception e) { + e.printStackTrace(); + throw new AssertionError("ListenerInfo::handle"); + } + } } + private static final class NotificationThread implements ThreadFactory { + final static ThreadFactory factory = new NotificationThread(); + private final static Executor executor = Executors.newSingleThreadExecutor(NotificationThread.factory()); + + static ThreadFactory factory() { + return factory; + } + + public Thread newThread(Runnable r) { + return AccessController.doPrivileged(new PrivilegedAction<>() { + @Override + public Thread run() { + Thread th = InnocuousThread.newThread(r); + th.setPriority(Thread.NORM_PRIORITY); + th.setName("Notification thread"); + th.setDaemon(true); + return th; + } + }); + } + } /** * Current list of listeners, a List of ListenerInfo. The object * referenced by this field is never modified. Instead, the field