如何从内部停止线程? [复制]

Posted

技术标签:

【中文标题】如何从内部停止线程? [复制]【英文标题】:How to stop a thread from inside? [duplicate] 【发布时间】:2021-04-03 03:24:10 【问题描述】:

考虑这段代码:-

class A 
    Thread t = new Thread() 
        @Override
        public void run() 
            super.run();
            
            // Tons of statements.... (Set 1)
            
            
            if(/* We don't meet certain requirements for continuing */) 
                
                // Exit and stop the thread and do not execute any following statements after the if block
                
            
            
            
            // Tons of statements.... (Set 2)
        
    ;
    
    public void run() 
        t.start();
    


class B 
    public static void main(String[] args) 
        A obj = new A();
        obj.run();
    

我们从 B 类的 main 开始我们的程序。

假设 B 类中的 main 完成了所有指令,而 Thread t 仍在执行集合 1 中的语句。

现在,t 停止的方式只有两种。要么到达语句集 2 的结尾(这将导致线程终止),要么 if 块停止 Thread t

我想知道如何实现这样的 if 块?

如果我只是写join(),那么Thread t 似乎不会执行furthur 命令,但它会保持活动状态并且不会消失(我从实验中观察到的情况)。

stop() 已折旧。那么实现必要的if 块的正确方法是什么。主体应该是什么,以便如果某些条件在 continuti 之前不满足,我们进入 if 块,然后代码结束线程而不执行任何进一步的指令(在 if 块下方),然后线程立即 DIES。

现在,很明显,一个简单而正确的解决方案就是将所有 SET2 指令放入 else 块中,

但我想知道是否有其他适当的方法可以做到这一点。

我正在制作一个基于文本的游戏,并创建了多个 Class A 实例。对于 A 的每个实例,我必须在多个地方进行此类检查。

将所有进一步的代码放在else 块中会使代码过于嵌套。缩进看起来很糟糕,感觉这不是正确的方法。

这也将帮助我更好地理解线程。启动线程很容易,但停止它们总是会让我的大脑付出沉重的代价。

【问题讨论】:

obj.run(); -- 这不是启动线程的方式。您将调用obj.start();,否则您的代码将在主方法所在的同一线程中运行。另外,为什么首先要扩展 Thread 呢?你不应该实现 Runnable 吗? if (condition) return; if (!condititon) /* Set 2 */ 。请记住,在 condition 中使用了由另一个线程设置的变量,我们需要保证跨线程可见性。 请检查以下线程中的第二个答案 - 更好的方式来指示其他线程停止:***.com/questions/6859681/… 【参考方案1】:

answer by Abra 是正确的。让我补充一下避免Thread的想法。

从 Java 5 开始,我们一般不再直接寻址 Thread 类。而是使用执行器服务。传递一个RunnableCallable,其代码就是您要执行的任务。

在你的主要方法中:

ExecutorService executorService = Executors. … ;

Runnable runnable = () -> 
     // Tons of statements … 
    if( whatever ) 
    
        return ;  // Method ends. So then thread ends or is returned to thread pool managed by the executor service.
    
    // …
    // Method ends. So then thread ends or is returned to thread pool managed by the executor service.
;

executorService.submit( runnable ) ; 
… 
executorService.shutdown() ;

未来,当 Project Loom 到来时,ExecutorService 将是AutoCloseable。所以我们可以在执行器服务中使用 try-with-resources 语法。并且try 语句将阻塞,直到所有提交的任务都完成(完成或中断)。执行器服务此时会自动关闭。

【讨论】:

很久没有回到这个问题上来看看我问这种问题有多愚蠢。但这也让我想感谢你(我应该早点做的)这个额外的技巧,它实际上以指数因子改善了我处理线程的方式。【参考方案2】:

线程在其run 方法完成时终止。 return 语句终止一个方法。由于方法run 不返回任何值,因此只需在if 块中写入return 将终止该方法并随后终止线程。

if(/* We don't meet certain requirements for continuing */) 
    return;

【讨论】:

以上是关于如何从内部停止线程? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何停止 Java 线程? [复制]

如何在一定时间到期后立即停止线程? [复制]

如何在android中安全地停止线程? [复制]

为啥我的布尔变量在停止线程循环时应该是可变的? [复制]

Java如何停止一个线程

Java如何停止一个线程