我对线程非常陌生,在代码中使用线程时,我面临以下问题。
点击一个按钮,我就启动了一个运行特定任务的线程,这个任务在系统的后台运行。我在线程中使用了一个while循环来检查一个易失性bool是否被另一个按钮点击来停止整个过程而改变。问题是我必须添加一个空循环,否则它看起来就像线程停止自己,不再检查while条件。我认为这是非常低效的,浪费了很多资源。
我添加了一个简短的代码版本,以减少不可读性。
你知道为什么会发生这种情况,以及如何提高代码的整体效率吗?
public void onClick(View view) {
new Thread(new Runnable() {
public void run() {
//execute my task
while(!stopThread) {
// Without this empty loop the thread stops after a while
}
while(stopThread) { // stopThread is a volatile bool changed by another button click
//Finish the task
break;
}
}
}).start();
}
我猜stopThread的初始值为false,这会导致第二个循环不执行,线程终止。
您可以在两个按钮之间共享一些锁对象,而不用使用循环,而是使用wait和notify。检查本教程。
可能的实现如下所示:
两个按钮都需要访问这两个变量:
Object lock = new Object();
volatile boolean stopThread = false;
第一个按钮的点击方法:
public void onClick(View view) {
new Thread(new Runnable() {
public void run() {
// execute my task
synchronized (lock) {
// stopThread is a volatile boolean changed by another button click
while (stopThread == false) {
lock.wait();
}
}
// Finish the task
}
}).start();
}
第二个按钮的onClick
方法:
public void onClick(View view) {
new Thread(new Runnable() {
public void run() {
synchronized (lock) {
stopThread = true;
lock.notify();
}
}
}).start();
}
您需要保留布尔标志以处理虚假唤醒。如果条件已满,则继续使用代码,否则返回等待通知。
注意,该示例不处理可能发生的任何中断。
您可能需要使用AsyncTask。执行,而不是自己启动线程
检查此答案。
问题内容: 我正在尝试在我正在处理的Python项目中使用线程,但是线程似乎没有按照我的代码的预期运行。似乎所有线程都按顺序运行(即,线程2在线程1结束后开始,它们不是同时启动)。我编写了一个简单的脚本来对此进行测试,并且该脚本也按顺序运行线程。 这是我从运行它得到的输出: 循环的迭代次数更多时,观察到相同的行为。 我尝试搜索网络和较早的SO答案,但找不到任何有帮助的方法。有人可以指出这段代码有什
问题内容: 我正在比较测试程序上的两个变体。两者都在具有四个内核的计算机上以4线程运行。 在“模式1”下,我非常类似于执行程序服务来使用池。我把一堆任务扔了进去。与普通的固定线程执行器服务相比,我获得了更好的性能(即使有对Lucene的调用,该调用在其中执行了一些I / O)。 这里没有分而治之。从字面上看,我知道 在“模式2”中,我向池提交一个任务,然后在该任务中调用ForkJoinTask.i
问题内容: 我想在线程中运行一个进程(正在对一个大的数据库表进行迭代)。在线程运行时,我只希望程序等待。如果该线程花费的时间超过30秒,我想终止该线程并执行其他操作。通过杀死线程,我的意思是我希望它停止活动并优雅地释放资源。 我想这样做是通过最好的方式的和功能,以及。使用I,我可以让我的程序等待30秒等待线程完成,并且通过使用该函数,我可以确定线程是否完成了工作。如果尚未完成工作,则设置事件,并且
在一个类中,在一个函数中,我创建了一个Tkinter画布。这个函数正在被另一个类调用,我希望Tkinter窗口弹出30秒,然后自动关闭。我有电话 但我犯了个错误 elf.tk.call('destroy',self.w)\u tkinter.TclError:无法调用“destroy”命令:应用程序已被销毁 那我怎么能让它自己关上呢?
请查看Oracle规范-第5章。 这一行: 拓宽的基元转换不会丢失有关数值的整体大小的信息。 接下来,就在下面两行,这一行说震级信息可能会丢失。 从float到double的非strictfp加宽原语转换可能会丢失有关转换值的总体大小的信息。 这似乎是一个明显的矛盾;这是一个错误吗?
问题内容: 这可能是一个重复的问题,但我没有找到想要的东西。我在UI活动中调用AsyncTask, 在doInBackground中调用需要时间的方法。如果一段时间后没有返回数据,我想中断该线程。以下是我尝试执行此操作的代码。 但这并不能在30秒后停止任务,事实上,这花费了更多时间。我也尝试过,但这也不起作用。 谁能告诉我该怎么做或如何在doInBackground中使用isCancelled()