首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Coding
V2EX  ›  Java

Java 如何强行停止一个线程?

  •  
  •   sadfQED2 · 76 天前 · 3806 次点击
    这是一个创建于 76 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Google 前几页的文章都看过了,没找到什么好办法,特来请教各位,我目前写的部分相当于一个框架,我提供 2 个按钮,开始和停止,点击开始后新启一个线程执行别人的代码,点击停止后杀掉这个线程,我并不能控制别人代码里面都判断了 InterruptedException 异常,那这种情况下我有什么办法强行停止线程内的操作呢? Thread.stop()方法已经被移除了,好像没有替代的了?

    24 回复  |  直到 2019-10-03 18:50:52 +08:00
        1
    wzwwzw   76 天前
    有 pid 么,交给操作系统杀掉。
        2
    sadfQED2   76 天前
    @wzwwzw #1

    ```
    Thread thread = new Thread(){
    @Override
    public void run() {
    // 执行别人的代码
    }
    };
    thread.start();
    ```

    不行吧?核心代码是这样的。点击停止按钮,执行
    ```
    thread.stop();
    ```
    但现在问题是 stop 方法已经被移除了
        3
    tachikomachann   76 天前 via Android
    Thread.stop() 之所以移除原因就是强制杀掉线程会有不可预料的错误。
    所以正确的做法是用类似信号量控制的方式,让线程安全退出。
        4
    Macolor21   76 天前
    class CustomThread implement Runnable{
    private boolean flag=true;
    @Override
    public void run() {
    while(flag){
    }
    }
        5
    Macolor21   76 天前
    @Macolor21 #4
    不小心发出去了,这是简单的信号量控制方法,不过对方的代码的执行不可控的话,只能等 gc?
        6
    aguesuka   76 天前 via Android
    最不差的方法可能是,用线程池,shutDownNow。如果能改接口,返回一个 Futrue,实现曲线。
        7
    pwrliang   76 天前 via Android
    没法控制别人的代码,那就起进程,直接杀掉
        8
    HuasLeung   76 天前 via Android
    信号量 semaphore
        9
    aguesuka   76 天前 via Android
    如果中断异常中断不了,那就用进程 start 和 kill
        10
    Takamine   76 天前 via Android
    用一个 SingleThreadPool 呢。
        11
    Raymon111111   76 天前
    把别人的代码放在 while(true) 里跑, 然后来个状态位
        12
    magiclz233   76 天前
    stop()强行停止,不建议使用了,如果你确定你的代码不会导致死锁或者数据不一致什么的,可以直接用 stop,或者用 interrupt,还有就是给线程代码中加异常,触发异常的话就会自动跳出了。又或者加判断条件。不过不推荐
        13
    sadfQED2   75 天前
    @Macolor21 #5 信号控制我当然知道啊,但是别人的逻辑并不确定,万一别人写个 while(true)呢。

    @Raymon111111 #11 别人的代码只是给我一个入口,只调用一次,并不是多次调用


    @magiclz233 #12 stop()已经移除了,强制杀死我也知道可能会出一些资源回收等等问题,但是因为没发控制别人的代码,所以必须得自己想办法出问题的时候保证能结束


    @aguesuka #6 @Takamine #10 我考虑下
        14
    Raymon111111   75 天前
    @sadfQED2 想想应该确实是做不到的, while(true) 这种应该是无法打断的.
        15
    helloSpringBoot   75 天前 via Android
    之前也想过这个问题,强行终止只有 stop,但是现在已经废弃,不推荐使用。
    其它只能是协作式终止,中断加 flag 标志一起使用。
    如果对方代码不响应中断,那没有安全的办法了。
    java 并发编程实战有一章专门讲了这个问题。
        16
    momocraft   75 天前
    子进程可能比较容易
        17
    coolcfan   75 天前
    线程池的 shutdownNow()也不能停止正在进行的任务。
        18
    lastpass   75 天前 via Android   ♥ 1
    如果你写的这个框架与你的应用不是同一个进程。
    继承对方的执行主类,添加一个停止的监听器方法。此监听被触发时,直接 system.exit()
        19
    sadfQED2   75 天前 via Android
    @lastpass 也不行,我是给别人提供一个回调函数,别人在回调函数里面写他的逻辑,在回调函数里面我并不知道他怎么写,他的主类是啥
        20
    STRRL   75 天前
    和他明确的说明要做 InterruptedException, 写到和他交接的文档里面.
        21
    yulon   75 天前
    合作:让他改。
    逆向:系统 API,做好崩溃的打算。
        22
    sadfQED2   75 天前
    @STRRL #20 嗯,好像确实没其他方法了,只有在文档里面加要求了


    @helloSpringBoot #15 安不安全无所谓,stop 已经没有了,不然我用 stop 就好了,我怕的是别人代码里面万一写个类似 while(true)的代码,跳不出来
        23
    0xZhangKe   74 天前
    用 flag 配合中断标志位。
    while(!stop){
    try{
    ...
    } catch(InteruptException e){
    if(stop) return;
    }
    }

    再向外部暴露一个停止线程方法:

    public void stop(){
    stop = true;
    yourThread.interrupt();
    }
        24
    kaminic   74 天前 via Android
    很明显,提需求让对方加退出接口,同时做好内部资源的释放
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2750 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 27ms · UTC 12:48 · PVG 20:48 · LAX 04:48 · JFK 07:48
    ♥ Do have faith in what you're doing.