如果方法调用超过10秒,我想杀死它并继续前进.
多线程是解决这个问题的唯一选择吗?
如果我使用多线程,我很新,我的run方法只包含一个方法,如下所示.如果myMethod()卡在无限循环中,有没有办法打断这个线程?
public void run() {
myMethod();
}
Run Code Online (Sandbox Code Playgroud)
我们假设myMethod()如下所示,更改它不是一个选项.
while(true){
System.out.println("Thinking.");
for (int i = 0; i < 100000; i++) {
//wasting time
}
}
Run Code Online (Sandbox Code Playgroud)
我打算使用Mik378的解决方案,但我认为这不会起作用,因为myMethod不会抛出InterruptedException异常.
我想知道如何在 Java 中停止一个无响应的线程,这样它就真的死了。
首先,我很清楚Thread.stop()被弃用以及为什么不应该使用它;关于这个主题已经有很多很好的答案,参见。[1] [2]。因此,更准确的问题是,从技术上讲,是否真的有可能杀死一个代码不受我们控制但可能具有敌意且不响应中断的线程。
在最简单的情况下,一个恶意线程正在运行while(true);,但它也可能耗尽内存或其他系统资源来造成更大的破坏。调用interrupt()那个线程显然是无效的。打电话stop()呢?
我已经在调试器中运行了它,事实上,线程真的消失了。但这种方法可靠吗?可以为这种情况准备敌对线程;想想try{run();}catch(ThreadDeath t){run();}它在哪里捕获ThreadDeath我们调用时产生的stop()并再次递归调用自身。
作为外部观察者,我们无法看到正在发生的事情;Thread.stop()总是默默地运行。最糟糕的是,通常的诊断将不再起作用(在 Corretto 1.8.0_275 Windows x64 上调试时试过这个):无论是否成功杀死线程,Thread.getState()总是返回RUNNABLE,同样适用Thread.isAlive()(总是如此)。
我有一个使用片段的MainActivity.
MainActivity的onCreate使用的完成onCreate
welcomeFragment = new MyWelcomeFragment();
fr.beginTransaction().replace(R.id.mainContent, welcomeFragment).commit()
Run Code Online (Sandbox Code Playgroud)
作为OnWesume上MyWelcomeFragment的一部分,一个线程开始从我的网络服务器获取更新.如果用户在线程完成之前选择了一个动作并转到MyNewsFragment,那么尚未完成在MyWelcomeFragment的线程堆栈中运行的线程会发生什么?
线程是用:( myThread和handler是实例变量)创建的
myThread = new Thread(new Runnable() {
@Override
public void run() {
sendDataToServer("");
handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
onTaskDone();
}
});
}
});
myThread.start();
Run Code Online (Sandbox Code Playgroud) 我正在使用基于Java的文件转换工具将PDF转换为DOCX,但有时在转换时它会卡住,如果输入文件大小超过1 MB并开始使用100%CPU和更多内存并继续运行.我想停止这个连续的线程.
stop()函数已被弃用.thread.interrupt();没有帮助,因为线程一直在运行.如何停止正在运行的线程t.
public class ThreadDemo implements Runnable {
Thread t;
PdfToDocConversion objPdfToDocConversion;
ThreadDemo() throws InterruptedException {
t = new Thread(this);
System.out.println("Executing " + t.getName());
// this will call run() fucntion
t.start();
Thread.sleep(2000);
// interrupt the threads
if (!t.interrupted()) {
System.out.println("Interrupted");
t.interrupt();
}
System.out.println(t.isInterrupted()); // true
System.out.println(t.getName());
System.out.println(t.isAlive()); /// still true
// block until other threads finish
try {
t.join();
} catch (InterruptedException e) {
}
}
public void run() {
objPdfToDocConversion = …Run Code Online (Sandbox Code Playgroud) 我在https://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html中阅读了有关结束线程的方法,这是我从问题How do you kill a Java中的线程?
在第一个链接中,他们首先讨论使用volatile变量向要终止的线程发出信号。线程应该检查此变量并在变量具有表示停止的值时停止操作(例如,如果是null)。因此,要终止线程,您需要将该变量设置为null.
然后他们讨论添加中断来帮助处理长时间阻塞的线程。他们给出了以下 stop() 方法示例,该方法将 volatile 变量(waiter)设置为 null,然后还引发中断。
public void stop() {
Thread moribund = waiter;
waiter = null;
moribund.interrupt();
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道,为什么你需要两者?为什么不只使用interrupt(),然后正确处理呢?这对我来说似乎是多余的。
所以我创建了一个线程
Thread personThread = new Thread(Person);
personThread.start();
/** Now to stop it **/
personThread.stop();
Run Code Online (Sandbox Code Playgroud)
问题是,当我尝试编译时,我得到:warning: [deprecation] stop() in Thread has been deprecated.据我所知,这已经不再使用了.那我怎么能完全停止一个线程,与它的状态无关呢?
嘿,我目前有一个我的Android应用程序的问题.我通过实现Excecutor接口启动了一个额外的线程:
class Flasher implements Executor {
Thread t;
public void execute(Runnable r) {
t = new Thread(r){
};
t.start();
}
}
Run Code Online (Sandbox Code Playgroud)
我像这样开始我的Runnable:
flasherThread.execute(flashRunnable);
Run Code Online (Sandbox Code Playgroud)
但是我怎么能阻止它呢?
我正在尝试终止一个线程,但它不会中断或停止。所有这些都是名为 Webots 的软件的控制器的一部分。我用它来模拟多机器人系统。在每个机器人的控制器中,我启动一个线程,通过机器人接收器接收消息。该线程必须首先启动,并在模拟结束时终止。
该线程的 run 方法如下所示:
public void run() {
while (true)
{
String M = recieveMessage();
char[] chars = M.toCharArray();
if(chars[0]==robotName||chars[0]=='0')
messages.add(M);
}
}
Run Code Online (Sandbox Code Playgroud)
在主控制器中,我的代码如下所示:
MessageThread MT = new MessageThread(messages, receiver,getName());
MT.start();
for (int i = 0; i < 100; i++)
{
try
{
Thread.sleep(25); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(messages.get(messages.size()-1));
}
MT.interrupt();//MT = null;
System.out.println(MT.interrupted());
Run Code Online (Sandbox Code Playgroud)
我在主控制器中做什么并不重要,所以不要评判它。例如,消息是一个 ArrayList。它就像一个缓冲区,MT 将消息放入其中,主线程从中读取。我使用它是因为接收器和发射器不同步。
如果我调用interrupt() 或MT = null 但interrupted() 它返回false 并且MT 继续运行。我的代码有什么问题吗?
我阅读了一些主题,例如:
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
等等,但我找不到任何有用的答案。
谢谢大家,我已经对我的代码进行了更改。我将此添加到 …
Thread d = new Thread(new Runnable() {
@Override
public void run() {
while(true);
}
});
d.start();
Run Code Online (Sandbox Code Playgroud)
如何在不更改方法内部的代码的情况下退出无限循环public void run(),并且不使用d.stop();(不推荐使用的方法).
PS:我更喜欢发布我需要做的整个练习细节.这有点像我需要吃的东西.他们给了我一个有时进入无限循环的函数,我无法改变那个方法.