0

我想和你分享我的想法。
考虑你必须自己实现一个线程池。

我认为它有一些像private static List<Thread>Threads 这样的成员字段作为我的“池”。

我也有两种方法
:从池中分配线程。
湾。它将一个线程返回到池中。

我的问题是
1. 你将如何保护它们List不被某些线程同时访问:
我想用 声明这两种方法synchronize,然后购买意识到这不好,因为我将无法执行以下操作:
将一个线程返回到池中,同时从池中取出一个。
我也想过使用像 Vector 这样的线程安全集合,但似乎也有同样的问题。

2.你认为线程池类应该是一个Singleton吗?您认为代码的哪一部分应该负责分配它的单个实例?

4

2 回答 2

0
  1. 我认为这是一个快速的操作:get、set、delete、add。所以,如果你希望它是线程保存的,你需要锁定机制
  2. 我想,这取决于你想要什么。在.NET中是单例的
  3. 我认为这不是 100% 适合提出问题的部分。
于 2013-01-28T14:57:34.113 回答
0

这个问题的关键取决于

您是否打算实际重用一个线程来运行多个任务,从而维护一个线程池而不终止它们 [A] 或

您是否打算将池仅作为限制来控制可以在任何给定点运行的同时任务的数量,并且在每次执行后线程将被终止,并且必须创建另一个线程来代替它。[乙]

如果未完成的作业请求的总数低于系统限制,则可以通过返回一个新的 Thread 对象来轻松实现 [B]。显然,线程对象在退出之前应该知道如何减少公共资源使用计数器。在这种情况下,您不必维护线程集合,而只需维护所有线程对公共引用计数对象(例如信号量)的引用。

[A] 但是,需要一个从 Thread 继承的类,该类在执行给定任务后不会退出,而是等待下一个任务执行。一旦此类可用,您可以简单地将适当的线程对象引用返回给调用者,并使用一个标记,该标记将以线程安全的方式将线程标记为已使用或未使用。

这是实现这一目标的一种简单方法

ArrayList<MyThread>      pool = new ArrayList<MyThread>      (DEFAULT_POOL SIZE);
ArrayList<AtomicBoolean> used = new ArrayList<AtomicBoolean> (DEFAULT_POOL SIZE);

如果您将 pool[i] 返回给调用者,请将其标记为正在使用,通过执行

used[i].set(true). 

当线程返回池时,将同一对象标记为未使用 (set(false)。显然,您可以从同步的分配/释放方法中执行此操作。由于它们是同步的,用于存储池线程的集合不需要同步,您可以使用任何结构/集合,具体取决于您使用的算法来确定接下来要发出哪个线程。

作为一种优化,您可以在第一次请求池化线程时即时创建池(和各个线程) - 这样您无需在它可用之前对其进行初始化。但是您需要以线程安全的方式进行操作,我不会详细说明。

至于问题 2,除非您想创建多个池,否则将池类设为单例是个好主意,如果不选中它会很危险。如果您使用的是非静态池对象,它还将使您无需跟踪实例化了多少此类池。

如前所述,您可以通过重新使用现有的线程池类来省去麻烦,这些线程池类为您很好地处理了场景 A :)

于 2013-01-28T18:09:13.387 回答