我可以阻止具有名称或字段的线程吗?

Can I block a thread with name or a field?

我有很多话题要开始。其中一些具有相同的名称。如果一个线程的名称与另一个线程 运行ning 相同,我想阻止该线程。但是如果没有同名的运行ning线程,它可以立即运行。

比如我有3个线程:A1、A2、B,还有一个线程池。 A1的名字是“A”,A2的名字是“A”,B的名字是“B”。当我执行线程时,如果启动顺序是 A1、A2、B,我希望 A2 在 A1 完成后 运行ning。但是 B 不受影响,因为它的名字不是“A”。所以B马上运行

有没有简单的工具?或者我必须使用地图?

一个线程无法安全地阻塞另一个 (non-cooperating) 线程。

有……Thread.suspend()……但是 javadoc 是这样说的:

Deprecated, for removal: This API element is subject to removal in a future version.

This method has been deprecated, as it is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as "frozen" processes. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.

即使有协作线程(其中一个线程自愿阻塞自身直到发生某些事情),我也不知道现有的并发性 class / API 提供了您所要求的;即根据线程名称控制任务序列。

也许您可以(并且应该)在不依赖线程名称的情况下完成您想要实现的目标。例如:

  • 您可以有多个执行器,每个执行器都有自己的队列和一个工作线程。一项用于“A”任务,一项用于“B”任务,依此类推。

  • 您可以使用 CompletionServiceCompletionStage 来实现。使“A2”成为消耗“A1”的 CompletionStage,依此类推。

我不能保证给你最好的解决方案,因为你没有描述你试图解决的根本问题。 (即,您没有在“XY Problem”中命名“Y”。)但是,也许我可以提供一些帮助。

听起来好像您的程序可能有不同的用户(“A”、“B”等),并且听起来好像程序创建了新的任务(“A1 "、"A2" 等)以响应用户输入。您希望与任何特定用户关联的任务按顺序执行,但您希望允许属于不同用户的任务同时执行。

现在,您为每个新任务创建一个新线程。这几乎不是一个好主意。一个更好的主意是拥有一个永远循环的 工作线程 的集合,从阻塞队列中挑选任务并执行它们:

import java.util.concurrent.BlockingQueue;

class Worker implements Runnable {
    private final BlockingQueue<Runnable> taskQueue;
    public Worker(BlockingQueue<Runnable> taskQueue) {
        this.taskQueue = taskQueue;
    }

    @override
    public void run() {
        while (true) {
            Runnable task = taskQueue.take();
            task.run();
        }
    }
}

这是一个简单的 线程池的核心。 Java 标准库有一个更复杂的线程池实现,ThreadPoolExecutor,但它没有不能完全按照您的意愿去做,因为它不能保证 运行 某些任务按顺序进行。

一个普通的线程池只有一个任务队列,所有工作线程take() 任务都来自这个任务队列。但是如果你有一个线程池,其中每个工作线程都有自己的队列,并且如果你的线程池有一个 Map<Category,BlockingQueue<task>> 那么它可以将属于同一类别(例如,同一用户)的所有任务分配给同一个工作线程,该线程将执行任务 one-by-one。同时,属于其他用户的任务可以分配给不同的工作人员,并且可以与第一个用户的任务同时执行。


我不知道有任何 ready-made 这个想法的实现。这是您必须自己编写代码的东西。还有,我这里没有space来谈细节,比如,如何选择worker的数量,如何将用户映射到worker,如何提供关闭机制(如果需要的话)等等

您可以随意变得复杂。特别是对于用户-> 工作者映射:如果用户 A 和 B 都映射到同一个工作者,并且当来自 B 的新请求进来而其他工作者空闲时,如果该工作者积压了来自 A 的请求,那么一个复杂的实施可能会更改用户 B 的映射。