JDK-4272445 : (thread) Need a way to override default inheritance of Thread daemon state
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.3.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 1999-09-16
  • Updated: 2005-10-25
  • Resolved: 2005-10-25
Related Reports
Relates :  
Description
Currently a newly created thread is initially marked as being a daemon 
thread if and only if the thread creating it is marked as a daemon thread.

We need a way to modify and control this behavior, i.e. to make a daemon 
thread spawn threads that will be initially marked as being non-daemon.

This change is required to fix the bug (bugtraq id 4030718 - A program which 
calls Toolkit.getDefaultToolkit() won't terminate - 136 JDC votes):

We are going to make Java event dispatch threads daemon. However this 
will break the existing client code that creates new threads on the event 
dispatch thread and doesn't explicitly set non-daemon status assuming that 
the creating thread is non-daemon.

Comments
EVALUATION There hasn't been any more rationale (or votes) for this RFE and defect CR 4030718 was fixed long ago without the need for it. This simply isn't justified.
25-10-2005

SUGGESTED FIX *** /tmp/geta22075 Thu Sep 16 19:24:44 1999 --- Thread.java Thu Sep 16 18:54:13 1999 *************** *** 27,34 **** * may or may not also be marked as a daemon. When code running in * some thread creates a new <code>Thread</code> object, the new * thread has its priority initially set equal to the priority of the ! * creating thread, and is a daemon thread if and only if the ! * creating thread is a daemon. * <p> * When a Java Virtual Machine starts up, there is usually a single * non-daemon thread (which typically calls the method named --- 27,36 ---- * may or may not also be marked as a daemon. When code running in * some thread creates a new <code>Thread</code> object, the new * thread has its priority initially set equal to the priority of the ! * creating thread. The initial daemon status of the newly created thread ! * can be controlled with <code>setDefaultChildDaemonStatus</code> method. ! * By default the created thread is marked as being a daemon thread if and ! * only if the thread creating it is currently marked as a daemon thread. * <p> * When a Java Virtual Machine starts up, there is usually a single * non-daemon thread (which typically calls the method named *************** *** 174,179 **** --- 176,206 ---- public final static int MAX_PRIORITY = 10; /** + * Specifies that new threads created on this thread will inherit + * the daemon status of this thread. + */ + public static final int INHERIT_DAEMON = 0x0; + + /** + * Specifies that new threads created on this thread will be initially + * daemon regardless of the daemon status of this thread. + */ + public static final int FORCE_DAEMON = 0x1; + + /** + * Specifies that new threads created on this thread will be initially + * non-daemon regardless of the daemon status of this thread. + */ + public static final int FORCE_NON_DAEMON = 0x2; + + /* + * Specifies whether new threads created on this thread will be + * initially daemon/non-daemon or they will inherit the daemon + * status of this thread. + */ + private int defaultChildDaemonStatus = INHERIT_DAEMON; + + /** * Returns a reference to the currently executing thread object. * * @return the currently executing thread. *************** *** 263,269 **** g.checkAccess(); this.group = g; ! this.daemon = parent.isDaemon(); this.priority = parent.getPriority(); this.name = name.toCharArray(); this.contextClassLoader = parent.contextClassLoader; --- 290,301 ---- g.checkAccess(); this.group = g; ! switch (parent.getDefaultChildDaemonStatus()) { ! case FORCE_DAEMON: this.daemon = true; break; ! case FORCE_NON_DAEMON: this.daemon = false; break; ! case INHERIT_DAEMON: ! default: this.daemon = parent.isDaemon(); break; ! } this.priority = parent.getPriority(); this.name = name.toCharArray(); this.contextClassLoader = parent.contextClassLoader; *************** *** 423,429 **** * thread. The method <code>setPriority</code> may be used to * change the priority to a new value. * <p> ! * The newly created thread is initially marked as being a daemon * thread if and only if the thread creating it is currently marked * as a daemon thread. The method <code>setDaemon </code> may be used * to change whether or not a thread is a daemon. --- 455,463 ---- * thread. The method <code>setPriority</code> may be used to * change the priority to a new value. * <p> ! * The initial daemon status of the newly created thread can be ! * controlled with <code>setDefaultChildDaemonStatus</code> method. ! * By default the created thread is marked as being a daemon * thread if and only if the thread creating it is currently marked * as a daemon thread. The method <code>setDaemon </code> may be used * to change whether or not a thread is a daemon. *************** *** 1023,1028 **** --- 1057,1130 ---- } /** + * Specifies whether new threads created on this thread will be + * initially daemon/non-daemon or they will inherit the daemon + * status of this thread. + * <p> + * This method must be called before the thread is started. + * <p> + * This method first calls the <code>checkAccess</code> method + * of this thread with no arguments. This may result in throwing a + * <code>SecurityException</code>(in the current thread). + * + * @param status if <code>INHERIT_DAEMON</code>, new threads created + * on this thread will inherit daemon status of this thread. + * if <code>FORCE_DAEMON</code>, new threads created + * on this thread will initially be daemon, regardless + * of the daemon status of this thread. + * if <code>FORCE_NON_DAEMON</code>, new threads created + * on this thread will initially be non-daemon, regardless + * of the daemon status of this thread. + * @exception IllegalArgumentException if the passed value is none of the + * predefined constants. + * @exception IllegalThreadStateException if this thread is active. + * @see java.lang.Thread#setDaemon(boolean) + * @see java.lang.Thread#isDaemon() + * @see java.lang.Thread#getDefaultChildDaemonStatus() + * @see java.lang.Thread#INHERIT_DAEMON + * @see java.lang.Thread#FORCE_DAEMON + * @see java.lang.Thread#FORCE_NON_DAEMON + */ + public final void setDefaultChildDaemonStatus(int status) { + checkAccess(); + if (isAlive()) { + throw new IllegalThreadStateException(); + } + switch (status) { + case INHERIT_DAEMON: + case FORCE_DAEMON: + case FORCE_NON_DAEMON: + defaultChildDaemonStatus = status; break; + default: + throw new IllegalArgumentException("Wrong status value"); + } + } + + /** + * Tests whether new threads created on this thread will be + * initially daemon/non-daemon or they will inherit the daemon + * status of this thread. + * + * @return <code>INHERIT_DAEMON</code>, if new threads created + * on this thread inherit daemon status of this thread. + * <code>FORCE_DAEMON</code>, if new threads created + * on this thread are initially marked as daemon threads, + * regardless of the daemon status of this thread. + * <code>FORCE_NON_DAEMON</code>, if new threads created + * on this thread are initially marked as non-daemon, + * thread regardless of the daemon status of this thread. + * @see java.lang.Thread#setDaemon(boolean) + * @see java.lang.Thread#isDaemon() + * @see java.lang.Thread#setDefaultChildDaemonStatus(int) + * @see java.lang.Thread#INHERIT_DAEMON + * @see java.lang.Thread#FORCE_DAEMON + * @see java.lang.Thread#FORCE_NON_DAEMON + */ + public final int getDefaultChildDaemonStatus() { + return defaultChildDaemonStatus; + } + + /** * Determines if the currently running thread has permission to * modify this thread. * <p>
11-06-2004

EVALUATION I have severe doubts as to whether this constitutes a reasonable modification to the Thread class. It complicates the model for little gain. If we were changing the model, I would be more tempted to provide a mechanism whereby a thread could change its daemon status (which is currently fixed once a thread is started). joshua.bloch@Eng 1999-09-30
30-09-1999