Package org.apache.harmony.lang.management

Source Code of org.apache.harmony.lang.management.ThreadMXBeanImpl

/*
* 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.harmony.lang.management;

import java.lang.management.ManagementPermission;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
* Runtime type for {@link java.lang.management.ThreadMXBean}
*
* @since 1.5
*/
public final class ThreadMXBeanImpl extends DynamicMXBeanImpl implements
        ThreadMXBean {

    private static ThreadMXBeanImpl instance = new ThreadMXBeanImpl();

    /**
     * Constructor intentionally private to prevent instantiation by others.
     * Sets the metadata for this bean.
     */
    private ThreadMXBeanImpl() {
        setMBeanInfo(ManagementUtils.getMBeanInfo(ThreadMXBean.class.getName()));
    }

    /**
     * Singleton accessor method.
     *
     * @return the <code>ThreadMXBeanImpl</code> singleton.
     */
    static ThreadMXBeanImpl getInstance() {
        return instance;
    }

    /**
     * @return an array of the identifiers of every thread in the virtual
     *         machine that has been detected as currently being in a deadlock
     *         situation.
     * @see #findMonitorDeadlockedThreads()
     */
    private native long[] findMonitorDeadlockedThreadsImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#findMonitorDeadlockedThreads()
     */
    public long[] findMonitorDeadlockedThreads() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(new ManagementPermission("monitor"));
        }
        return this.findMonitorDeadlockedThreadsImpl();
    }

    /**
     * @return the identifiers of all of the threads currently alive in the
     *         virtual machine.
     * @see #getAllThreadIds()
     */
    private native long[] getAllThreadIdsImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getAllThreadIds()
     */
    public long[] getAllThreadIds() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(new ManagementPermission("monitor"));
        }
        return this.getAllThreadIdsImpl();
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getCurrentThreadCpuTime()
     */
    public long getCurrentThreadCpuTime() {
        return getThreadCpuTime(Thread.currentThread().getId());
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getCurrentThreadUserTime()
     */
    public long getCurrentThreadUserTime() {
        return getThreadUserTime(Thread.currentThread().getId());
    }

    /**
     * @return the number of currently alive daemon threads.
     * @see #getDaemonThreadCount()
     */
    private native int getDaemonThreadCountImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getDaemonThreadCount()
     */
    public int getDaemonThreadCount() {
        return this.getDaemonThreadCountImpl();
    }

    /**
     * @return the peak number of live threads
     * @see #getPeakThreadCount()
     */
    private native int getPeakThreadCountImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getPeakThreadCount()
     */
    public int getPeakThreadCount() {
        return this.getPeakThreadCountImpl();
    }

    /**
     * @return the number of currently alive threads.
     * @see #getThreadCount()
     */
    private native int getThreadCountImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getThreadCount()
     */
    public int getThreadCount() {
        return this.getThreadCountImpl();
    }

    /**
     * @param id
     *            the identifier for a thread. Must be a positive number greater
     *            than zero.
     * @return on virtual machines where thread CPU timing is supported and
     *         enabled, and there is a living thread with identifier
     *         <code>id</code>, the number of nanoseconds CPU time used by
     *         the thread. On virtual machines where thread CPU timing is
     *         supported but not enabled, or where there is no living thread
     *         with identifier <code>id</code> present in the virtual machine,
     *         a value of <code>-1</code> is returned.
     * @see #getThreadCpuTime(long)
     */
    private native long getThreadCpuTimeImpl(long id);

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getThreadCpuTime(long)
     */
    public long getThreadCpuTime(long id) {
        // Validate input.
        if (id <= 0) {
            throw new IllegalArgumentException(
                    "Thread id must be greater than 0.");
        }

        long result = -1;
        if (isThreadCpuTimeSupported()) {
            if (isThreadCpuTimeEnabled()) {
                result = this.getThreadCpuTimeImpl(id);
            }
        } else {
            throw new UnsupportedOperationException(
                    "CPU time measurement is not supported on this virtual machine.");
        }
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getThreadInfo(long)
     */
    public ThreadInfo getThreadInfo(long id) {
        return getThreadInfo(id, 0);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getThreadInfo(long[])
     */
    public ThreadInfo[] getThreadInfo(long[] ids) {
        return getThreadInfo(ids, 0);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getThreadInfo(long[], int)
     */
    public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(new ManagementPermission("monitor"));
        }

        // Validate inputs
        for (int i = 0; i < ids.length; i++) {
            if (ids[i] <= 0) {
                throw new IllegalArgumentException(
                        "Thread id must be greater than 0.");
            }
        }

        if (maxDepth < 0) {
            throw new IllegalArgumentException(
                    "maxDepth value cannot be negative.");
        }

        // Create an array and populate with individual ThreadInfos
        ThreadInfo[] tis = new ThreadInfo[ids.length];
        for (int i = 0; i < ids.length; i++) {
            tis[i] = this.getThreadInfoImpl(ids[i], maxDepth);
        }
        return tis;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getThreadInfo(long, int)
     */
    public ThreadInfo getThreadInfo(long id, int maxDepth) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(new ManagementPermission("monitor"));
        }

        // Validate inputs
        if (id <= 0) {
            throw new IllegalArgumentException(
                    "Thread id must be greater than 0.");
        }
        if (maxDepth < 0) {
            throw new IllegalArgumentException(
                    "maxDepth value cannot be negative.");
        }
        return this.getThreadInfoImpl(id, maxDepth);
    }

    /**
     * Returns the corresponding Thread instance for a given thread id
     *
     * @param id
     *            id of the thread (must be > 0)
     * @return null if thread with the id specified does not exist
     */
    private native Thread getThreadByIdImpl(long id);

    /**
     * Returns the object the thread is either blocked or waiting on
     *
     * @param thread
     *            thread
     * @return null if thread not blocked on an object
     */
    private native Object getObjectThreadIsBlockedOnImpl(Thread thread);

    /**
     * Returns the thread owning an object
     *
     * @param obj
     *            object
     * @return null if object not owned, else Thread owner
     */
    private native Thread getThreadOwningObjectImpl(Object obj);

    /**
     * Returns whether the thread is suspended or not
     *
     * @param thread
     *            thread
     * @return true if Thread.suspend() has been called on the thread, otherwise
     *         false
     */
    private native boolean isSuspendedImpl(Thread thread);

    /**
     * Returns the number of times the thread has waited
     *
     * @param thread
     *            thread
     * @return number of times the thread has waited
     *
     */
    private native long getThreadWaitedCountImpl(Thread thread);

    /**
     * Returns the amount of time the thread has waited (in milliseconds)
     *
     * @param thread
     *            thread
     * @return time (in milliseconds) the thread has waited, or -1 if this
     *         feature is not supported
     *
     */
    private native long getThreadWaitedTimeImpl(Thread thread);

    /**
     * Returns the amount of time the thread has blocked (in milliseconds)
     *
     * @param thread
     *            thread
     * @return time (in milliseconds) the thread has blocked, or -1 if this
     *         feature is not supported
     *
     */
    private native long getThreadBlockedTimeImpl(Thread thread);

    /**
     * Returns the number of times the thread has blocked on a monitor
     *
     * @param thread
     *            thread
     * @return number of times the thread has blocked
     *
     */
    private native long getThreadBlockedCountImpl(Thread thread);

    /**
     * Create an instance of the ThreadInfo class
     *
     * @param threadId
     * @param threadName
     * @param threadState
     * @param suspended
     * @param inNative
     * @param blockedCount
     * @param blockedTime
     * @param waitedCount
     * @param waitedTime
     * @param lockName
     * @param lockOwnerId
     * @param lockOwnerName
     * @param stackTrace
     * @return
     */
    private native ThreadInfo createThreadInfoImpl(long threadId,
            String threadName, Thread.State threadState, boolean suspended,
            boolean inNative, long blockedCount, long blockedTime,
            long waitedCount, long waitedTime, String lockName,
            long lockOwnerId, String lockOwnerName,
            StackTraceElement[] stackTrace);

    /*
     * Get together information for a thread and create an instance of the
     * ThreadInfo class
     *
     * @param id thread id @param maxDepth maximum depth of the stack trace
     * @return an instance of ThreadInfo for valid thread ids, otherwise null
     *
     */
    private ThreadInfo getThreadInfoImpl(long id, int maxDepth) {
        final Thread thread = getThreadByIdImpl(id);
        if (null == thread) {
            return null;
        }

        // Generic thread info
        long threadId = thread.getId();
        String threadName = thread.getName();
        Thread.State threadState = thread.getState();

        // Waited and blocked information
        long waitedTime = -1;
        long blockedTime = -1;
        // Waited and blocked times to be -1 if ThreadContentionMonitoring
        // is not supported
        if (isThreadContentionMonitoringSupported()
                && isThreadContentionMonitoringEnabled()) {
            waitedTime = getThreadWaitedTimeImpl(thread);
            blockedTime = getThreadBlockedTimeImpl(thread);
        }

        // Get together information about any locks involved
        // i.e. thread blocked or waiting on a lock
        // see ThreadInfo spec for values if neither blocked nor waiting
        String lockName = null;
        long lockOwnerId = -1;
        String lockOwnerName = null;

        Object lock = getObjectThreadIsBlockedOnImpl(thread);
        if (lock != null) {
            // the format of the name is dictated by the ThreadInfo spec
            lockName = lock.getClass().getName() + '@'
                    + Integer.toHexString(System.identityHashCode(lock));
            Thread threadOwningLock = getThreadOwningObjectImpl(lock);
            // Possible race conditions must be catered for
            if (threadOwningLock != null) {
                lockOwnerId = threadOwningLock.getId();
                lockOwnerName = threadOwningLock.getName();
            }// end if non-null thread owning lock
        }// end if non-null lock

        // Get the stack trace together.
        // Do we have to prune it for max depth?
        StackTraceElement[] stackTrace = AccessController
                .doPrivileged(new PrivilegedAction<StackTraceElement[]>() {
                    public StackTraceElement[] run() {
                        return thread.getStackTrace();
                    }// end method run
                });

        boolean isInNative = false;
        if (stackTrace.length > 0) {
            isInNative = stackTrace[0].isNativeMethod();
        }
        if ((maxDepth < Integer.MAX_VALUE) && (stackTrace.length > maxDepth)) {
            StackTraceElement[] newStackTrace = new StackTraceElement[maxDepth];
            for (int i = 0; i < newStackTrace.length; i++) {
                newStackTrace[i] = stackTrace[i];
            }
            stackTrace = newStackTrace;
        }

        // Ask our native to instantiate a ThreadInfo for us
        ThreadInfo ti = createThreadInfoImpl(threadId, threadName, threadState,
                isSuspendedImpl(thread), isInNative,
                getThreadBlockedCountImpl(thread), blockedTime,
                getThreadWaitedCountImpl(thread), waitedTime, lockName,
                lockOwnerId, lockOwnerName, stackTrace);
        return ti;
    }

    /**
     * @param id
     *            the identifier for a thread. Must be a positive number greater
     *            than zero.
     * @return on virtual machines where thread CPU timing is supported and
     *         enabled, and there is a living thread with identifier
     *         <code>id</code>, the number of nanoseconds CPU time used by
     *         the thread running in user mode. On virtual machines where thread
     *         CPU timing is supported but not enabled, or where there is no
     *         living thread with identifier <code>id</code> present in the
     *         virtual machine, a value of <code>-1</code> is returned.
     *         <p>
     *         If thread CPU timing was disabled when the thread was started
     *         then the virtual machine is free to choose any measurement start
     *         time between when the virtual machine started up and when thread
     *         CPU timing was enabled with a call to
     *         {@link #setThreadCpuTimeEnabled(boolean)}.
     *         </p>
     * @see #getThreadUserTime(long)
     */
    private native long getThreadUserTimeImpl(long id);

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getThreadUserTime(long)
     */
    public long getThreadUserTime(long id) {
        // Validate input.
        if (id <= 0) {
            throw new IllegalArgumentException(
                    "Thread id must be greater than 0.");
        }

        long result = -1;
        if (isThreadCpuTimeSupported()) {
            if (isThreadCpuTimeEnabled()) {
                result = this.getThreadUserTimeImpl(id);
            }
        } else {
            throw new UnsupportedOperationException(
                    "CPU time measurement is not supported on this virtual machine.");
        }
        return result;
    }

    /**
     * @return the total number of started threads.
     * @see #getTotalStartedThreadCount()
     */
    private native long getTotalStartedThreadCountImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#getTotalStartedThreadCount()
     */
    public long getTotalStartedThreadCount() {
        return this.getTotalStartedThreadCountImpl();
    }

    /**
     * @return <code>true</code> if CPU timing of the current thread is
     *         supported, otherwise <code>false</code>.
     * @see #isCurrentThreadCpuTimeSupported()
     */
    private native boolean isCurrentThreadCpuTimeSupportedImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#isCurrentThreadCpuTimeSupported()
     */
    public boolean isCurrentThreadCpuTimeSupported() {
        return this.isCurrentThreadCpuTimeSupportedImpl();
    }

    /**
     * @return <code>true</code> if thread contention monitoring is enabled,
     *         <code>false</code> otherwise.
     * @see #isThreadContentionMonitoringEnabled()
     */
    private native boolean isThreadContentionMonitoringEnabledImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#isThreadContentionMonitoringEnabled()
     */
    public boolean isThreadContentionMonitoringEnabled() {
        if (!isThreadContentionMonitoringSupported()) {
            throw new UnsupportedOperationException(
                    "Thread contention monitoring is not supported on this virtual machine.");
        }
        return this.isThreadContentionMonitoringEnabledImpl();
    }

    /**
     * @return <code>true</code> if thread contention monitoring is supported,
     *         <code>false</code> otherwise.
     * @see #isThreadContentionMonitoringSupported()
     */
    private native boolean isThreadContentionMonitoringSupportedImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#isThreadContentionMonitoringSupported()
     */
    public boolean isThreadContentionMonitoringSupported() {
        return this.isThreadContentionMonitoringSupportedImpl();
    }

    /**
     * @return <code>true</code> if thread CPU timing is enabled,
     *         <code>false</code> otherwise.
     * @see #isThreadCpuTimeEnabled()
     */
    private native boolean isThreadCpuTimeEnabledImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#isThreadCpuTimeEnabled()
     */
    public boolean isThreadCpuTimeEnabled() {
        if (!isThreadCpuTimeSupported()) {
            throw new UnsupportedOperationException(
                    "Thread CPU timing is not supported on this virtual machine.");
        }
        return this.isThreadCpuTimeEnabledImpl();
    }

    /**
     * @return <code>true</code> if the virtual machine supports the CPU
     *         timing of threads, <code>false</code> otherwise.
     * @see #isThreadCpuTimeSupported()
     */
    private native boolean isThreadCpuTimeSupportedImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#isThreadCpuTimeSupported()
     */
    public boolean isThreadCpuTimeSupported() {
        return this.isThreadCpuTimeSupportedImpl();
    }

    /**
     * @see #resetPeakThreadCount()
     */
    private native void resetPeakThreadCountImpl();

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#resetPeakThreadCount()
     */
    public void resetPeakThreadCount() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(new ManagementPermission("control"));
        }
        this.resetPeakThreadCountImpl();
    }

    /**
     * @param enable
     *            enable thread contention monitoring if <code>true</code>,
     *            otherwise disable thread contention monitoring.
     */
    private native void setThreadContentionMonitoringEnabledImpl(boolean enable);

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#setThreadContentionMonitoringEnabled(boolean)
     */
    public void setThreadContentionMonitoringEnabled(boolean enable) {
        if (!isThreadContentionMonitoringSupported()) {
            throw new UnsupportedOperationException(
                    "Thread contention monitoring is not supported on this virtual machine.");
        }

        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(new ManagementPermission("control"));
        }
        this.setThreadContentionMonitoringEnabledImpl(enable);
    }

    /**
     * @param enable
     *            enable thread CPU timing if <code>true</code>, otherwise
     *            disable thread CPU timing
     */
    private native void setThreadCpuTimeEnabledImpl(boolean enable);

    /*
     * (non-Javadoc)
     *
     * @see java.lang.management.ThreadMXBean#setThreadCpuTimeEnabled(boolean)
     */
    public void setThreadCpuTimeEnabled(boolean enable) {
        if (!isThreadCpuTimeSupported()) {
            throw new UnsupportedOperationException(
                    "Thread CPU timing is not supported on this virtual machine.");
        }

        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(new ManagementPermission("control"));
        }
        this.setThreadCpuTimeEnabledImpl(enable);
    }
}
TOP

Related Classes of org.apache.harmony.lang.management.ThreadMXBeanImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.