java thread programming 1.5 - Gracefully Stopping Threads


interrupt()
While one thread is running, another thread can interrupt it by invoking its corresponding Thread object’s interrupt() method:
public void interrupt()
 
This method simply sets a flag in the destination thread indicating that it has been interrupted and returns right away. It is possible that a SecurityException will be thrown by interrupt(), indicating that the thread requesting the interrupt does not have permission to interrupt the other thread. The security check is done by invoking the checkAccess() method on Thread, which in turn checks whether a SecurityManager has been installed, and if so, invokes its checkAccess(Thread) method. An in-depth exploration of security in Java is beyond the scope of this book, but you should note that some methods of Thread and ThreadGroup could throw SecurityExceptions.
 
本方法修改线程标志位表明线程已经中断,立刻返回,在某些安全要求比较高的环境(applet)如果存在SecuityManager可能会抛出SecurityException异常。
 
isInterrupted()
You can check the interrupted status of any thread by invoking the isInterrupted() method on the Thread object:
public boolean isInterrupted()
 
This does not alter the status, but simply returns true if the thread has been interrupted and its interrupted flag has not yet been cleared.
 
探测线程是否中断,本函数执行完毕,中断标志位不被清除
 
Thread.interrupted()
You can use the Thread.interrupted() method to check (and implicitly reset to false) the interrupted status of the current thread:
public static boolean interrupted()
 
Because it is static, it cannot be invoked on a particular thread, but can only report the interrupted status of the thread that invoked it. This method returns true if the thread has been interrupted and its interrupted flag has not yet been cleared. Unlike isInterrupted(), it automatically resets the interrupted flag to false. Invoking Thread.interrupted() a second time would always return false unless the thread was reinterrupted. Listing 5.4 shows an example of how you can use Thread.interrupted().
 
探测线程是否中断,本程序执行完毕,中断标志重置为false
 
Deprecated Methods suspend() and resume()
 
The Thread API contains two deprecated methods that are used to temporarily stop and later restart a thread:
public final void suspend()
public final void resume()
 
Methods and classes are deprecated by Sun Microsystems to indicate that developers should avoid using them. A deprecated method can still be used, but when the code is compiled, a warning is issued. Deprecation is used to indicate a method or class is obsolete or dangerous and may be removed from future releases of the JDK. Although you may still use deprecated methods, you should use them sparingly and only when absolutely necessary.
 
suspend()挂起线程
resume()恢复线程执行
@Deprecation 表明此方法不推荐使用,在jdk将来版本可能会被剔出
 
The suspend() method is deprecated as of JDK 1.2 because if a thread is suspended at an inopportune time—such as when it is holding a lock for a shared resource—a deadlock condition may result. I explain and demonstrate deadlocks in Chapter 7, “Concurrent Access to Objects and Variables,” but let it suffice to say for now that a deadlock is a very bad thing and can cause a program to freeze up on a user. Even when locks are not involved, a thread might be suspended while in the middle of a long procedure that really should not be left in a partially completed state. The resume() method is deprecated because without any use of suspend(), it is not needed.
 
不推荐使用suspend()的原因:
1、  当线程占有某些共享资源时,将其挂起,很容易造成死锁,
2、  当执行某些不能被部分完成的大操作时,线程可能会被挂起
不推荐使用resume()的原因是因为不推荐使用suspend()
 
Deprecated Method stop()
At times, one of the additional threads spawned in a multithreaded program is no longer needed, but it continues to execute statements—perhaps in an infinite loop. The Thread API includes a stop() method to abruptly terminate a thread’s execution:
public final void stop()
 
When this method is invoked on a thread, the thread immediately throws a java.lang.ThreadDeath error (a subclass of java.lang.Error, which itself is a subclass of java.lang.Throwable). This exception propagates up the method call stack, executing any finally clauses present and releasing any locks that are currently held. Ultimately, this exception causes run() to abruptly return, and the thread dies.
 
调用stop()方法时,线程会立刻抛出ThreadDeath error(java.lang.Error的子类,java.lang.Error本身是java.lang.Throwable的子类),线程会释放所有锁,run()立刻返回,线程死亡
 
The stop() method is deprecated as of JDK 1.2 because it can lead to corrupted data in objects. One problem is that when a thread is stopped abruptly, there is little opportunity to perform any cleanup work. Another problem is that when stop() is invoked on a thread, the thread releases all the locks it is currently holding. The locks are definitely being held for a good reason—probably to keep other threads from accessing data elements that are not yet in a consistent state. This sudden release of the locks may leave some data in some objects in an inconsistent state with no warning about the possible corruption. In many cases, there are other ways to have a thread return from run() in an orderly manner that leaves all objects in a consistent state.
 
stop被取消的原因:
1、  当一个线程被粗暴中止,可能还没有进行清除工作
2、  锁机制就是防止访问共同资源其他线程处于不连续状态,线程被stop之后,会释放其拥有所有锁,造成其它线程不连续
 
An Alternative to stop():变通方法
AlternateStop.java源码
/*
 * Created on 2005-7-8
 *
 * Java Thread Programming - Paul Hyde
 * Copyright ? 1999 Sams Publishing
 * Jonathan Q. Bo 学习笔记
 *
 */
 
package org.tju.msnrl.jonathan.thread.chapter1;
 
/**
 * @author Jonathan Q. Bo from TJU MSNRL
 *
 * Email:jonathan.q.bo@gmail.com
 * Blog:blog.csdn.net/jonathan_q_bo
 *      blog.yesky.net/jonathanundersun
 *
 * Enjoy Life with Sun!
 *
 */
 
public class AlternateStop implements Runnable {
 
    private Thread runThread;
       private volatile boolean stopRequest;
 
    /*
     * @see java.lang.Runnable#run()
     */
    public void run() {
        this.runThread = Thread.currentThread();
        stopRequest = false;
       
        int counter = 0;
        while(!stopRequest){
            System.out.println("running ... ... count = " + counter);
            counter++;
           
            try{
                Thread.sleep(300);
            }catch(InterruptedException e){
                Thread.currentThread().interrupt();
            }
        }
    }
   
    public void stopThread(){
        this.stopRequest = true;
        if(this.runThread != null){
            this.runThread.interrupt();
        }
    }
 
    public static void main(String[] args) {
        AlternateStop at = new AlternateStop();
        Thread newThread = new Thread(at);
        newThread.start();
        try{
            Thread.sleep(2000);
        }catch(InterruptedException e){
            System.out.println(e.getMessage());
        }
        at.stopThread();
    }
}
 
Daemon Threads
Threads that are marked as daemons stop in a whole new way. Daemon threads are used for background supporting tasks and are only needed while normal, nondaemon threads are still running. When the VM detects that the only remaining threads are daemon threads, it exits. If any nondaemon thread is still alive, the VM will not exit. Daemon threads provide a nice way of managing some sort of behind-the-scenes processing that is only necessary to support other nondaemon threads.
 
守护线程:当其他通常的非守护线程运行时,后台执行;当其他线程结束,剩下的都是守护线程时,虚拟机停止守护线程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这句话的意思是:nodemanager没有在5秒内优雅地停止,所以使用kill -9命令强制杀掉了它。nodemanager是一个管理Node.js应用程序的工具,可能由于某些原因无法正常停止,需要使用kill命令强制终止。 ### 回答2: nodemanager是Hadoop中用于管理Node进程的一种组件,它可以监控Node的状态,启动或停止Node进程。在Hadoop启动时,nodemanager会自动启动,当需要停止Node进程时,nodemanager也需要进行相应的操作。 但是,在某些情况下,nodemanager可能会出现异常情况,比如在停止Node进程时,nodemanager未能正常关闭,这时就会出现类似“nodemanager did not stop gracefully after 5 seconds: killing with kill -9”的提示信息。 这个提示信息的意思是,nodemanager在尝试停止Node进程时,已经超过了5秒钟的时间限制,但它仍未能正常关闭,因此,操作系统采取了“kill -9”命令来强制终止nodemanager进程。这样做的目的是防止nodemanager继续占用系统资源,从而影响Hadoop集群的正常运行。 造成nodemanager未能正常关闭的原因可能有很多,比如操作系统资源不足、网络故障等。在遇到这种情况时,我们可以通过查看日志文件来进一步了解问题所在,然后尝试重新启动nodemanager进程或者调整系统配置以解决问题。 总之,nodemanager did not stop gracefully after 5 seconds: killing with kill -9是Hadoop集群中的一种常见提示信息,它提示我们nodemanager未能正常关闭,需要我们进一步排查问题并采取相应的措施以保证集群的正常运行。 ### 回答3: "nodemanager did not stop gracefully after 5 seconds: killing with kill -9"这个错误信息是在Hadoop集群中出现的,它通常是向NodeManager发送shutdown信号时,发现NodeManager没有正常关闭,而需要通过kill命令强制杀掉。这种情况一般是由于NodeManager的运行环境遇到了一些无法处理的异常导致的,如JVM崩溃、内存泄漏或者系统资源耗尽等。 当Hadoop集群中的NodeManager进程无法正常停止时,可能会产生一些严重的问题,如内存泄漏、资源占用等,导致整个集群的效率受到影响。为了避免这种情况的发生,我们可以采取以下几种措施: 1.审查NodeManager日志,查找异常信息,添加相关的调试信息。根据日志中的异常信息,可以更好地定位到问题所在,从而采取相应的处理措施。 2.重启NodeManager进程。如果发现NodeManager进程无法正常关闭,则可以考虑通过重启进程的方式来解决问题。可将进程kill掉,然后重新启动。 3.升级软件版本。如果集群中的软件版本较老,可能存在一些已解决的bugs或已优化的性能问题。因此,升级软件版本可能会带来更好的性能和更稳定的运行环境。 4.优化系统性能。在NodeManager运行过程中,可能会遇到系统资源耗尽的情况,如内存不足、磁盘过载等。因此,我们需要对系统环境进行适当的优化,如增加内存、升级硬件设备等,以提高系统性能和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值