我在我的一个活动中实现了AsyncTask:
performBackgroundTask asyncTask = new performBackgroundTask();
asyncTask.execute();
Run Code Online (Sandbox Code Playgroud)
现在,我需要实现"取消"按钮功能,所以我必须停止执行正在运行的任务.我不知道如何停止运行任务(后台任务).
所以请建议我,如何有力地取消AsyncTask?
我找到Cancel()了相同的方法,但我发现调用cancel(boolean mayInterruptIfRunning)不一定会停止执行后台进程.似乎发生的一切是AsyncTask将执行onCancelled(),并且在完成时不会运行onPostExecute().
这里的答案似乎是Java 8之前的有效解决方案: 如何在Java中取消Files.copy()?
但现在它不起作用,因为它ExtendedCopyOption.INTERRUPTIBLE是私人的.
基本上,我需要从一些给定的文件下载文件URL并使用它保存到我的本地文件系统Files.copy().目前,我正在使用JavaFX服务,因为我需要在a中显示进度ProgressBar.
但是,Files.copy()如果操作时间过长,我不知道如何阻止线程运行.使用Thread.stop()至少是不需要的.甚至Thread.interrupt()失败了.
如果互联网连接不可用,我还希望操作正常终止.
为了测试没有互联网连接时的情况,我将移除以太网线并在3秒后将其重新放回.不幸的是,Files.copy()只有当我放回以太网电缆时返回,而我希望它立即失败.
正如我所看到的,内部Files.copy()正在运行一个循环,这会阻止线程退出.
Tester(下载OBS Studio exe):
/**
* @author GOXR3PLUS
*
*/
public class TestDownloader extends Application {
/**
* @param args
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
// Block From exiting
Platform.setImplicitExit(false);
// Try to download the File from URL
new DownloadService().startDownload(
"https://github.com/jp9000/obs-studio/releases/download/17.0.2/OBS-Studio-17.0.2-Small-Installer.exe", …Run Code Online (Sandbox Code Playgroud) 我使用AsyncTask连接URLPath,如下面的代码.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.left_list);
Button btn = (Button)findViewById(resid);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//how to stop connect
}
});
new Connecting().execute();
}
class Connecting extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
//do something
}
@Override
protected String doInBackground(String... aurl) {
try {
URL url = new URL(URLPath);
connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
is = connection.getInputStream();
}
catch (Exception e) {
e.printStackTrace();
}
return null; …Run Code Online (Sandbox Code Playgroud) 当Thread.interrupt()在某个线程上调用a时,该线程会发生什么?
我完全理解它的作用(至少我希望如此).它并没有真正中断线程.它成功了Thread.isInterrupted(),代码应该检查什么方法并停止线程本身.
我的问题是,为什么我们甚至需要这种方法?它似乎完全可以通过声明一个布尔标志来说明是否应该停止此线程?没有任何Java教科书使用此布尔标志作为如何使用volatile关键字的最佳示例吗?
我特别困惑,因为似乎没有办法"不中断"线程,因为Thread.resume()已弃用.这interrupt()比我自己写的布尔标志更有用.
除了可能更容易编写之外,Thread.interrupt()还有什么不同于我的布尔标志?
我想知道如何在 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()(总是如此)。
我试图了解ReentrantLock如何在java中工作.
让我们考虑一个简单的例子如下:
private ReentrantLock lock;
public void foo() {
lock.lock();
try{
...
}finally {
lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
我试图弄清楚lock()方法的调用层次结构.
public void lock() {
sync.lock();
}
Run Code Online (Sandbox Code Playgroud)
对于FairSync:
final void lock() {
acquire(1);
}
Run Code Online (Sandbox Code Playgroud)
对于NonFairSync:
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
Run Code Online (Sandbox Code Playgroud)
两个lock()方法都调用参数为1的acquire()方法.
在AbstractQueuedSynchronizer类中:
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
static void selfInterrupt() {
Thread.currentThread().interrupt();
}
Run Code Online (Sandbox Code Playgroud)
如果当前线程无法获取资源(即某个其他线程已获取此资源),则当前线程必须等待.在这种情况下,ReentrantLock调用selfInterrupt()方法.
现在我的问题是interrupt()方法如何能够停止一个等同于synchronized中的wait()方法的线程?
另外,在资源被另一个线程释放后,currentThread如何自动启动?(在内部调用的另一个线程调用unlock()方法之后sync.release(1);)
我也试图找出如何中断()方法的工作原理在这里却找不到答案,我的问题.
try或catch块被中断时finally块是什么时候不执行的?doc说"如果执行try或catch代码的线程被中断或终止,即使整个应用程序继续执行,finally块也可能无法执行".有人能举例说明这种情况吗?
来自Java,我习惯于遵循以下习惯用法
while (true) {
try {
someBlockingOperation();
} catch (InterruptedException e) {
Thread.currentThread.interrupt(); // re-set the interrupted flag
cleanup(); // whatever is necessary
break;
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,它可以在整个JDK中处理任何可能阻塞的内容,例如从文件读取,从套接字读取,从队列读取甚至对于Thread.sleep()。
阅读有关如何在Rust中完成此操作的信息,我发现了许多看似特殊的解决方案,例如mio,tokio。我也找到ErrorKind::Interrupted并尝试ErrorKind通过发送SIGINT到线程来解决这个问题,但是线程似乎立即死亡而没有留下任何(返回)跟踪。
这是我使用的代码(注意:Rust还不很精通,因此看起来可能有些奇怪,但是可以运行):
use std::io;
use std::io::Read;
use std::thread;
pub fn main() {
let sub_thread = thread::spawn(|| {
let mut buffer = [0; 10];
loop {
let d = io::stdin().read(&mut buffer);
println!("{:?}", d);
let n = d.unwrap();
if n == 0 { …Run Code Online (Sandbox Code Playgroud) 我有一个我无法编辑的Java应用程序启动java.lang.Thread具有此run()方法的应用程序:
public void run(){
while(true){
System.out.println("Something");
}
}
Run Code Online (Sandbox Code Playgroud)
在某个时间点我想阻止它.如果我使用Thread.interrupt()它不起作用.如果我使用Thread.stop()它,但不推荐使用此方法(因此不鼓励使用它,因为它可能会在新版本中从JVM中删除).
如何在Java中停止这种不间断的线程?