/**
* Forces the thread to stop executing.
* <p>
* If there is a security manager installed, its <code>checkAccess</code>
* method is called with <code>this</code>
* as its argument. This may result in a
* <code>SecurityException</code> being raised (in the current thread).
* <p>
* If this thread is different from the current thread (that is, the current
* thread is trying to stop a thread other than itself), the
* security manager's <code>checkPermission</code> method (with a
* <code>RuntimePermission("stopThread")</code> argument) is called in
* addition.
* Again, this may result in throwing a
* <code>SecurityException</code> (in the current thread).
* <p>
* The thread represented by this thread is forced to stop whatever
* it is doing abnormally and to throw a newly created
* <code>ThreadDeath</code> object as an exception.
* <p>
* It is permitted to stop a thread that has not yet been started.
* If the thread is eventually started, it immediately terminates.
* <p>
* An application should not normally try to catch
* <code>ThreadDeath</code> unless it must do some extraordinary
* cleanup operation (note that the throwing of
* <code>ThreadDeath</code> causes <code>finally</code> clauses of
* <code>try</code> statements to be executed before the thread
* officially dies). If a <code>catch</code> clause catches a
* <code>ThreadDeath</code> object, it is important to rethrow the
* object so that the thread actually dies.
* <p>
* The top-level error handler that reacts to otherwise uncaught
* exceptions does not print out a message or otherwise notify the
* application if the uncaught exception is an instance of
* <code>ThreadDeath</code>.
*
* @exception SecurityException if the current thread cannot
* modify this thread.
* @see #interrupt()
* @see #checkAccess()
* @see #run()
* @see #start()
* @see ThreadDeath
* @see ThreadGroup#uncaughtException(Thread,Throwable)
* @see SecurityManager#checkAccess(Thread)
* @see SecurityManager#checkPermission
* @deprecated This method is inherently unsafe. Stopping a thread with
* Thread.stop causes it to unlock all of the monitors that it
* has locked (as a natural consequence of the unchecked
* <code>ThreadDeath</code> exception propagating up the stack). If
* any of the objects previously protected by these monitors were in
* an inconsistent state, the damaged objects become visible to
* other threads, potentially resulting in arbitrary behavior. Many
* uses of <code>stop</code> should be replaced by code that simply
* modifies some variable to indicate that the target thread should
* stop running. The target thread should check this variable
* regularly, and return from its run method in an orderly fashion
* if the variable indicates that it is to stop running. If the
* target thread waits for long periods (on a condition variable,
* for example), the <code>interrupt</code> method should be used to
* interrupt the wait.
* For more information, see
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
*/
@Deprecated
public final void stop() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
checkAccess();
if (this != Thread.currentThread()) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// A zero status value corresponds to "NEW", it can't change to
// not-NEW because we hold the lock.
if (threadStatus != 0) {
resume(); // Wake up thread if it was suspended; no-op otherwise
}
// The VM can handle all thread states
stop0(new ThreadDeath());
}
其实注释中也写了,只不过很少有人看,大部分的人都是从八股文中得知,只知其一未知其二,
现在就先来看看它的实现干了啥
private native void stop0(Object o);
native方法直接找对应的jni
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},
{"suspend0", "()V", (void *)&JVM_SuspendThread},
{"resume0", "()V", (void *)&JVM_ResumeThread},
{"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority},
{"yield", "()V", (void *)&JVM_Yield},
{"sleep", "(J)V", (void *)&JVM_Sleep},
{"currentThread", "()" THD, (void *)&JVM_CurrentThread},
{"countStackFrames", "()I", (void *)&JVM_CountStackFrames},
{"interrupt0", "()V", (void *)&JVM_Interrupt},
{"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted},
{"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock},
{"getThreads", "()[" THD, (void *)&JVM_GetAllThreads},
{"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads},
{"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName},
};
再看具体的实现函数
JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable))
JVMWrapper("JVM_StopThread");
oop java_throwable = JNIHandles::resolve(throwable);
if (java_throwable == NULL) {
THROW(vmSymbols::java_lang_NullPointerException());
}
oop java_thread = JNIHandles::resolve_non_null(jthread);
JavaThread* receiver = java_lang_Thread::thread(java_thread);
Events::log_exception(JavaThread::current(),
"JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]",
receiver, (address)java_thread, throwable);
// First check if thread is alive
if (receiver != NULL) {
// Check if exception is getting thrown at self (use oop equality, since the
// target object might exit)
if (java_thread == thread->threadObj()) {
THROW_OOP(java_throwable);
} else {
// Enques a VM_Operation to stop all threads and then deliver the exception...
Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable));
}
}
else {
// Either:
// - target thread has not been started before being stopped, or
// - target thread already terminated
// We could read the threadStatus to determine which case it is
// but that is overkill as it doesn't matter. We must set the
// stillborn flag for the first case, and if the thread has already
// exited setting this flag has no affect
java_lang_Thread::set_stillborn(java_thread);
}
JVM_END
主要就是把ThreadDeath异常抛出去,在抛出去之前看了看是不是当前线程执行的,不是的话给vm thread 在安全点执行
/**
* An instance of {@code ThreadDeath} is thrown in the victim thread
* when the (deprecated) {@link Thread#stop()} method is invoked.
*
* <p>An application should catch instances of this class only if it
* must clean up after being terminated asynchronously. If
* {@code ThreadDeath} is caught by a method, it is important that it
* be rethrown so that the thread actually dies.
*
* <p>The {@linkplain ThreadGroup#uncaughtException top-level error
* handler} does not print out a message if {@code ThreadDeath} is
* never caught.
*
* <p>The class {@code ThreadDeath} is specifically a subclass of
* {@code Error} rather than {@code Exception}, even though it is a
* "normal occurrence", because many applications catch all
* occurrences of {@code Exception} and then discard the exception.
*
* @since JDK1.0
*/
public class ThreadDeath extends Error {
private static final long serialVersionUID = -4417128565033088268L;
}
具体的实现就是上面的,那么废弃的原因是啥
为什么 Thread.stop 被弃用?
因为它本质上是不安全的。停止线程会导致它解锁已锁定的所有显示器 原文链接在下
https://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html