为对象定义线程 ID 并中断
Defining a thread id to a object and interrupt
我在系统上有专供用户使用的线程,我希望能够单独停止它们,我是否在创建时将线程 ID 与用户数据一起存储,然后调用中断?或者我可以以某种方式将线程添加到我的用户对象中,然后像 myuser.mythread.interrupt();
一样调用它,或者这是魔法?
目前我可以停止它们并在没有我想要的线程的情况下重新启动。
但这是一项耗时的任务,还会引发用户必须等待的延迟。
更新,这可以作为答案吗?
if(delete==true) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete=false;
}
}
更新
我设法找到了使用 myuser.mythread.interrupt() 的方法;
或者有点..
我将线程作为子 class 添加到用户 class 并在用户 class 中创建了一个方法来启动和中断,现在我可以启动和停止线程
online.get(1).hellos();
online.get(1).hellosStop();
无需创建引用并跟踪除用户对象以外的任何其他内容。
更新(关于接受的答案,使用id作为参考我可以这样做)
public class MyRunnable implements Runnable {
private boolean runThread = true;
@Override
public void run() {
try {
while (runThread) {
if(delete==true) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete=false;
}
}
Thread.sleep(5);
}
}
catch (InterruptedException e) {
// Interrupted, no need to check flag, just exit
return;
}
}
}
您可以只存储 Thread
引用,也许在 WeakReference
中,这样如果线程自行退出,线程就会消失。
但是您也可以让线程时不时地检查一个 AtomicBoolean(或 volatile 布尔值)以查看它是否被中断,这样您就不需要对线程的引用。
请注意,如果没有您要停止的线程的合作,停止 Java 中的线程是不可能的。使用 interrupt
或它检查的布尔值并不重要,在这两种情况下,都由线程检查这些标志(interrupt
只是设置一个标志)然后执行一些操作,例如退出。
更新
示例可中断线程 class:
public class MyRunnable implements Runnable {
private final AtomicBoolean stopFlag;
public MyRunnable(AtomicBoolean stopFlag) {
this.stopFlag = stopFlag;
}
@Override
public void run() {
try { // Try/Catch only needed if you use locks/sleep etc.
while (!stopFlag.get()) {
// Do some work, but remember to check flag often!
}
}
catch (InterruptedException e) {
// Interrupted, no need to check flag, just exit
return;
}
}
}
最好的方法是保存 Thread
引用并使其可供需要中断它的代码使用。
(对于非沙盒应用程序)遍历所有 JVM 现有线程的树来测试每个线程在技术上是可能的。然而,这很昂贵并且无法扩展。如果您可以存储或传递线程的 ID,那么您应该能够存储或传递 Thread
引用。
在技术上也可以创建您自己的 WeakHashMap<Long, Thread>
并使用它来将线程 ID 映射到线程。但同样的论点也适用....
你问这是不是解决方案:
if (delete) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete = false;
}
}
不,不是。或者更准确地说,它只会在线程中断自身的情况下 "work" 。在其他情况下,目标线程不会被中断。
根据您的用例,另一种方法是使用 ExecutionService
而不是裸线程。 submit
方法 return 代表提交任务的 Future
对象。该对象有一个 cancel(...)
方法,可用于在任务运行之前或通过中断 运行 线程来取消任务。
我在系统上有专供用户使用的线程,我希望能够单独停止它们,我是否在创建时将线程 ID 与用户数据一起存储,然后调用中断?或者我可以以某种方式将线程添加到我的用户对象中,然后像 myuser.mythread.interrupt();
一样调用它,或者这是魔法?
目前我可以停止它们并在没有我想要的线程的情况下重新启动。 但这是一项耗时的任务,还会引发用户必须等待的延迟。
更新,这可以作为答案吗?
if(delete==true) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete=false;
}
}
更新
我设法找到了使用 myuser.mythread.interrupt() 的方法; 或者有点..
我将线程作为子 class 添加到用户 class 并在用户 class 中创建了一个方法来启动和中断,现在我可以启动和停止线程
online.get(1).hellos();
online.get(1).hellosStop();
无需创建引用并跟踪除用户对象以外的任何其他内容。
更新(关于接受的答案,使用id作为参考我可以这样做)
public class MyRunnable implements Runnable {
private boolean runThread = true;
@Override
public void run() {
try {
while (runThread) {
if(delete==true) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete=false;
}
}
Thread.sleep(5);
}
}
catch (InterruptedException e) {
// Interrupted, no need to check flag, just exit
return;
}
}
}
您可以只存储 Thread
引用,也许在 WeakReference
中,这样如果线程自行退出,线程就会消失。
但是您也可以让线程时不时地检查一个 AtomicBoolean(或 volatile 布尔值)以查看它是否被中断,这样您就不需要对线程的引用。
请注意,如果没有您要停止的线程的合作,停止 Java 中的线程是不可能的。使用 interrupt
或它检查的布尔值并不重要,在这两种情况下,都由线程检查这些标志(interrupt
只是设置一个标志)然后执行一些操作,例如退出。
更新 示例可中断线程 class:
public class MyRunnable implements Runnable {
private final AtomicBoolean stopFlag;
public MyRunnable(AtomicBoolean stopFlag) {
this.stopFlag = stopFlag;
}
@Override
public void run() {
try { // Try/Catch only needed if you use locks/sleep etc.
while (!stopFlag.get()) {
// Do some work, but remember to check flag often!
}
}
catch (InterruptedException e) {
// Interrupted, no need to check flag, just exit
return;
}
}
}
最好的方法是保存 Thread
引用并使其可供需要中断它的代码使用。
(对于非沙盒应用程序)遍历所有 JVM 现有线程的树来测试每个线程在技术上是可能的。然而,这很昂贵并且无法扩展。如果您可以存储或传递线程的 ID,那么您应该能够存储或传递 Thread
引用。
在技术上也可以创建您自己的 WeakHashMap<Long, Thread>
并使用它来将线程 ID 映射到线程。但同样的论点也适用....
你问这是不是解决方案:
if (delete) {
if (Thread.currentThread().getId() == deleteId) {
Thread.currentThread().interrupt();
delete = false;
}
}
不,不是。或者更准确地说,它只会在线程中断自身的情况下 "work" 。在其他情况下,目标线程不会被中断。
根据您的用例,另一种方法是使用 ExecutionService
而不是裸线程。 submit
方法 return 代表提交任务的 Future
对象。该对象有一个 cancel(...)
方法,可用于在任务运行之前或通过中断 运行 线程来取消任务。