简体   繁体   English

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

[英]Can I block a thread with name or a field?

I have many threads to start.我有很多话题要开始。 Some of them have the same name.其中一些具有相同的名称。 I want to block a thread if its name is the same with another thread which is running.如果一个线程的名称与正在运行的另一个线程相同,我想阻止该线程。 But if there is not a running thread with the same name, it can run immediately.但是如果没有正在运行的同名线程,它可以立即运行。

For example, I have 3 threads: A1, A2, B, and a thread pool.例如,我有 3 个线程:A1、A2、B 和一个线程池。 A1's name is "A", A2's name is "A", B's name is "B". A1的名字是“A”,A2的名字是“A”,B的名字是“B”。 When I execute the threads, if the start sequence is A1, A2, B, I want A2 is running after A1 has finished.当我执行线程时,如果启动顺序是 A1、A2、B,我希望 A2 在 A1 完成后运行。 But B is not affected for it's name is not "A".但是 B 不受影响,因为它的名字不是“A”。 So B will run immediately.所以 B 会立即运行。

Is there a simple implement?有没有简单的实现? or I have to use Map?或者我必须使用 Map?

I can't promise to give you the best solution because you have not described the underlying problem that you are trying to solve.我不能 promise 给你最好的解决方案,因为你没有描述你试图解决的潜在问题。 (Ie, you have not named the "Y" in " XY Problem .") But, maybe I can offer some help. (即,您没有在“ XY 问题”中命名“Y”。)但是,也许我可以提供一些帮助。

It sounds as if your program maybe has different users ("A", "B", etc.) and it sounds as if the program creates new tasks ("A1", "A2", etc.) in response to user input.听起来好像您的程序可能有不同的用户(“A”、“B”等),并且程序似乎创建新任务(“A1”、“A2”等)以响应用户输入。 You want the tasks associated with any particular user to be executed sequentially, but you want to allow tasks belonging to different users to be executed concurrently.您希望与任何特定用户关联的任务按顺序执行,但您希望允许属于不同用户的任务同时执行。

Right now, you create a new thread for every new task.现在,您为每个新任务创建一个新线程。 That's almost never a good idea.这几乎不是一个好主意。 A better idea is to have a collection of worker threads that loop forever, picking tasks from a blocking queue and executing them:一个更好的想法是拥有一组永远循环的工作线程,从阻塞队列中挑选任务并执行它们:

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();
        }
    }
}

That's the heart of a simplistic thread pool.这是简单线程池的核心。 The Java standard library has a much more sophisticated thread pool implementation, ThreadPoolExecutor , but it doesn't quite do what you want because it won't guarantee to run certain tasks sequentially. Java 标准库有一个复杂得多的线程池实现ThreadPoolExecutor ,但它并不能完全满足您的要求,因为它不能保证按顺序运行某些任务。

A normal thread pool has just one task queue from which all of the worker threads take() tasks.一个普通的线程池只有一个任务队列,所有工作线程都take()任务。 But if you had a thread pool in which each worker had its own queue, and if your thread pool had a Map<Category,BlockingQueue<task>> then it could assign all of the tasks belonging to the same category (eg, to the same user) to the same worker thread, and that thread would perform the tasks one-by-one.但是如果你有一个线程池,其中每个工作者都有自己的队列,并且如果你的线程池有一个Map<Category,BlockingQueue<task>>那么它可以分配属于同一类别的所有任务(例如,到同一用户)到同一个工作线程,该线程将一个接一个地执行任务。 Meanwhile, tasks belonging to other users could be assigned to different workers, and they could be executed concurrently with the first user's tasks.同时,属于其他用户的任务可以分配给不同的工作人员,并且可以与第一个用户的任务同时执行。


I don't know of any ready-made implementation of this idea.我不知道这个想法有任何现成的实现。 It's something you'd have to code for yourself.这是您必须自己编写代码的东西。 Also, I don't have space here to talk about details such as, how to choose the number of workers, how to map users to workers, how to provide a shutdown mechanism (if needed) etc.另外,我这里没有篇幅来谈论细节,例如,如何选择 worker 的数量,如何将 map 用户分配给 worker,如何提供关闭机制(如果需要)等。

You could get arbitrarily sophisticated.你可以任意复杂。 Especially with the user->worker mapping: If Users A and B both map to the same worker, and if that worker has a backlog of requests from A when a new request from B comes in while some other worker is idle, then a sophisticated implementation might change the mapping for user B.特别是对于用户->工人映射:如果用户 A 和 B 都是 map 到同一个工人,并且如果当来自 B 的新请求进来而其他工人空闲时该工人积压了来自 A 的请求,那么一个复杂的实现可能会更改用户 B 的映射。

One thread can't safely block another (non-cooperating) thread.一个线程无法安全地阻塞另一个(非合作)线程。

There is... Thread.suspend() ... but the javadoc says this:有…… Thread.suspend() ……但是 javadoc 是这样说的:

Deprecated, for removal: This API element is subject to removal in a future version.已弃用,删除:此 API 元素可能会在未来版本中删除。

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?有关详细信息,请参阅为什么不推荐使用Thread.stopThread.suspendThread.resume . .

Even with cooperating threads (where one thread voluntarily blocks itself until something happens) I am not aware of an existing concurrency class / API that provides what you are asking for;即使有合作线程(一个线程自愿阻塞自己直到发生某些事情)我也不知道现有的并发 class / API 提供了你所要求的; ie controlling task sequences based on thread names.即根据线程名称控制任务序列。

Maybe you can (and should) do what you want to achieve without relying on thread names.也许您可以(并且应该)在不依赖线程名称的情况下完成您想要实现的目标。 For example:例如:

  • You could have a multiple executors each with its own queue, and a single worker thread.您可以有多个执行程序,每个执行程序都有自己的队列和一个工作线程。 One for the "A" tasks, one for the "B" tasks, and so on.一个用于“A”任务,一个用于“B”任务,依此类推。

  • You could implement this with CompletionService and CompletionStage .您可以使用CompletionServiceCompletionStage来实现它。 Make "A2" a CompletionStage that consumes "A1", and so on.使“A2”成为消耗“A1”的CompletionStage ,依此类推。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM