我想和你分享我的想法 考虑一下你必须自己实现一个线程池。
我想到让一些成员字段如线程的private static List<Thread>
成为我的“池”。
我也有两种方法:
一个。从池中分配线程。
湾哪个线程返回池中。
我的问题是:
1.如何保护List
不被某些线程同时访问:
我想用synchronize
声明这两种方法,然后意识到它不好,因为我无法做到以下几点:
将一个线程返回到池中,同时从中获取一个线程
我还想过使用像Vector这样的线程安全集合,但看起来它有同样的问题。
2.您认为线程池类应该是Singleton
吗?你认为应该负责分配单个实例的代码的哪一部分?
答案 0 :(得分:0)
答案 1 :(得分:0)
这个问题的关键取决于
是否打算重新使用线程来运行多个任务,从而维护一个线程池而不终止它们[A]或
你是否只想将池作为限制来控制可以在任何给定点运行的同时任务的数量,并且在每次执行之后线程将被终止并且必须创建另一个以取代它。 [B]
如果未完成的作业请求总数低于系统限制,则返回新的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).
将相同的对象标记为未使用(当线程返回到池时设置(false)。显然,您将通过synchronized allocate / deallocate方法执行此操作。由于它们是同步的,因此用于存储池化线程的集合不需要同步,你可以使用任何结构/集合,具体取决于你用来确定下一个线程的算法。
作为优化,您可以在第一次请求池化线程时动态创建池(以及各个线程) - 这样您就不需要初始化它直到它可用。但是你需要以线程安全的方式来做,我不会进入其中的细节。
至于问题2,除非你想创建多个池,否则最好让你的池类成为单例,如果它未经检查就会很危险。如果您使用的是非静态池对象,它还可以减轻您跟踪实例化实例化数量的问题。
如上所示,您可以通过重新使用处理场景A的现有线程池类来节省您的麻烦:)