java 两阶段终止线程的正确做法

目录
  • 一、怎么优雅地关闭一个线程?
    • 1.错误做法
    • 2.正确做法
  • 二、要点

一、怎么优雅地关闭一个线程?

在一个线程T1中如何优雅地关闭线程T2(也就是说要给T2一个机会释放持有的资源)?

1.错误做法

使用stop()方法停止线程:

stop()方法会真正杀死线程,如果此时该线程持有锁,那么其他线程将永远无法获取锁。

使用System.exit()方法停止线程:

会让整个进程都退出

2.正确做法

思路:

代码实现:

public class Test {
    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();
        twoPhaseTermination.start();

        Thread.sleep(3000);
        twoPhaseTermination.stop();

    }
}

class TwoPhaseTermination{
    // 监控线程
    private Thread monitorThread;

    public void start(){
        monitorThread = new Thread(()->{
            Thread current = Thread.currentThread();
            while(true){
                if(current.isInterrupted()){

                    System.out.println("线程要关闭了...");
                    break;
                }
                try {
                    Thread.sleep(1000); // 阶段1
                    System.out.println("监控线程正在工作...."); // 阶段2
                     // 如果在阶段2被打断,线程的isInterrupted标志位为true,会捕抓到信号并关闭线程
                     // 如果在阶段1被打断,会进入catch语句块,并且isInterrupted标志位清空,无法关闭线程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    // 需要重新设置isInterrupted标志位为true
                    monitorThread.interrupt();
                }
            }

        });
        // 启动线程
        monitorThread.start();
    }

    public void stop(){
        // 设置isInterrupted标志位true
        monitorThread.interrupt();
    }
}

运行结果:

两阶段关闭线程:

二、要点

为什么需要在catch代码块中重新执行monitorThread.interrupt()?因为Thread.sleep()执行过程中被打断,isInterrupted标志位会清空,下一次进入while循环就会忽略这次打断,继续运行线程。

演示一下把monitorThread.interrupt()注释掉的结果:

可以看到,会忽略这次的isInterrupted信号,继续运行线程。

到此这篇关于java 两阶段终止线程的正确做法的文章就介绍到这了,更多相关java 两阶段终止线程内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 正确终止线程的方法

    Thread类中有一个已经废弃的 stop() 方法,它可以终止线程,但由于它不管三七二十一,直接终止线程,所以被废弃了.比如,当线程被停止后还需要进行一些善后操作(如,关闭外部资源),使用这个方法就无能为力了.可以通过线程中断来实现线程终止. 首先来看一下Java线程中断的一些内容: Java平台为每个线程维护了一个布尔型的中断标记,可以通过下列方法获取该标记的值: interrupt() 中断某个线程             isInterrupted() 返回该线程的中断标记       

  • Java如何使用interrupt()终止线程

    一.interrupt() 说明 interrupt()的作用是中断本线程. 本线程中断自己是被允许的:其它线程调用本线程的interrupt()方法时,会通过checkAccess()检查权限.这有可能抛出SecurityException异常. 如果本线程是处于阻塞状态:调用线程的wait(), wait(long)或wait(long, int)会让它进入等待(阻塞)状态,或者调用线程的join(), join(long), join(long, int), sleep(long), sl

  • JAVA中 终止线程的方法介绍

    在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(), stop(), stop(Throwable) and suspend(), destroy() and resume().通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留. 在Sun公司的一篇文章<Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? >中详细讲解了舍弃这些方

  • Java中终止线程的三种方法

    Thread.stop, Thread.suspend, Thread.resume 和Runtime.runFinalizersOnExit 这些终止线程运行的方法已经被废弃,使用它们是极端不安全的! 1.线程正常执行完毕,正常结束 也就是让run方法执行完毕,该线程就会正常结束. 但有时候线程是永远无法结束的,比如while(true). 2.监视某些条件,结束线程的不间断运行 需要while()循环在某以特定条件下退出,最直接的办法就是设一个boolean标志,并通过设置这个标志来控制循环

  • Java中终止线程的方法详解

    Java中终止线程的方式主要有三种: 1.使用stop()方法,已被弃用.原因是:stop()是立即终止,会导致一些数据被到处理一部分就会被终止,而用户并不知道哪些数据被处理,哪些没有被处理,产生了不完整的"残疾"数据,不符合完整性,所以被废弃.So, forget it! 2.使用volatile标志位 看一个简单的例子: 首先,实现一个Runnable接口,在其中定义volatile标志位,在run()方法中使用标志位控制程序运行 public class MyRunnable i

  • Java实现终止线程池中正在运行的定时任务

    最近项目中遇到了一个新的需求,就是实现一个可以动态添加定时任务的功能.说到这里,有人可能会说简单啊,使用quartz就好了,简单粗暴.然而quartz框架太重了,小项目根本不好操作啊.当然,也有人会说,jdk提供了timer的接口啊,完全够用啊.但是我们项目的需求完全是多线程的模型啊,而timer是单线程的,so,楼主最后还是选择了jdk的线程池. 线程池是什么 Java通过Executors提供四种线程池,分别为: newCachedThreadPool :创建一个可缓存线程池,如果线程池长度

  • java 两阶段终止线程的正确做法

    目录 一.怎么优雅地关闭一个线程? 1.错误做法 2.正确做法 二.要点 一.怎么优雅地关闭一个线程? 在一个线程T1中如何优雅地关闭线程T2(也就是说要给T2一个机会释放持有的资源)? 1.错误做法 使用stop()方法停止线程: stop()方法会真正杀死线程,如果此时该线程持有锁,那么其他线程将永远无法获取锁. 使用System.exit()方法停止线程: 会让整个进程都退出 2.正确做法 思路: 代码实现: public class Test { public static void m

  • Java多线程 两阶段终止模式Two-Phase Termination Patter

    目录 1.两阶段终止模式介绍 2.Terminator代码演示 3.TerminationRequester 4.模拟客户端或者服务端都可能终止服务的例子 5.mac telnet模拟客户端输入 1.两阶段终止模式介绍 有时候,我们希望提前结束线程,但安全可靠地停止线程,并不是一件容易的事情,如果立即停止线程,会使共享的数据结构处于不一致的状态,如目前已经废弃使用的Thread类的stop方法(它会使线程在抛出java.lang.ThreadDeath之后终止线程,即使是在执行synchroni

  • Java 并发编程之线程挂起、恢复与终止

    挂起和恢复线程 Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的.如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能会发生死锁条件--其他线程在等待该线程释放锁,但该线程却被挂起了,便会发生死锁.另外,在长时间计算期间挂起线程也可能导致问题. 下面的代码演示了通过休眠来延缓运行,模拟长时间运行的情况,使线程更可能在不适当的时候被挂起: public class DeprecatedSuspendResume

  • Java语言多线程终止中的守护线程实例

    Java中线程分为两种类型:用户线程和守护(服务)线程.通过Thread.setDaemon(false)设置为用户线程;通过Thread.setDaemon(true)设置为守护线程;不设置则默认为用户线程. 结束单线程用 Thread.interrupt() 方法,多线程结束则需要设置守护线程.当不存在用户线程时,守护线程就会全部终结(可以理解为:守护线程是服务线程,用户线程是被服务线程,用户线程(被服务线程)全都没有了,服务线程便没有存在意义而自动终结) 例子: class StopThr

  • java两个线程同时写一个文件

    本文实例为大家分享了java两个线程同时写一个文件的具体代码,供大家参考,具体内容如下 1.多线程    线程是程序执行流的最小单元.是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源.一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行.由于线程之间的相互制约,致使线程在运行中呈现出间断性.线程也有就绪.阻塞和运行三种基本状态.就绪状态是指线程具备运行的所有条

  • 详解Java多线程编程中线程的启动、中断或终止操作

    线程启动: 1.start() 和 run()的区别说明 start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法.start()不能被重复调用. run() : run()就和普通的成员方法一样,可以被重复调用.单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程! 下面以代码来进行说明. class MyThread extends Thread{ public void run(){ ... } }; MyThread mythread = new

  • Java通过关闭Socket终止线程

    本文实例为大家分享了Java关闭Socket实现终止线程的具体代码,供大家参考,具体内容如下 package Threads; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; /** * Created by Frank */ public class StopClose extends Thread { pro

  • Java终止线程实例和stop()方法源码阅读

    了解线程 概念 线程 是程序中的执行线程.Java 虚拟机允许应用程序并发地运行多个执行线程. 线程特点 拥有状态,表示线程的状态,同一时刻中,JVM中的某个线程只有一种状态; ·NEW 尚未启动的线程(程序运行开始至今一次未启动的线程) ·RUNNABLE 可运行的线程,正在JVM中运行,但它可能在等待其他资源,如CPU. ·BLOCKED 阻塞的线程,等待某个锁允许它继续运行 ·WAITING 无限等待(再次运行依赖于让它进入该状态的线程执行某个特定操作) ·TIMED_WAITING 定时

随机推荐