Best practice for thread arrays (java)

2020-02-15 05:48发布

I have some experience with threading in java, but I am wondering...

What's the best practise to store multiple threads where I can access them both individually and as a group?

My own solution is to create a threadArray class but naturally I would prefer a native class that is much more reliable.

Thanks in advance!


edit

Apparently the functionality is of great importance of the best method. Well, I'll give an example:

I've got an application that basically searches through a lot of information at the same time hence I'm using threads. The threads however each need to perform just a part of the entire operation so I wish to add additional parameters to specify a range.

When a thread finishes it's specific search it can just stop naturally. When a thread finds a result however, I wish to stop all threads and retrieve that result.

Does that help?

5条回答
家丑人穷心不美
2楼-- · 2020-02-15 05:58

Why not use one of Java's Collection Framework?

I have used a Map to store threads, the purpose was for an online game so I stored the reference to client threads in a map with the character name (which was unique) as the key to the thread.

Just choose the collection that best suits your needs.

Along with this you can use methods in the Collections class to create synchronized versions of the Collections as needed.

查看更多
闹够了就滚
3楼-- · 2020-02-15 06:01

I often simply place Thread references inside standard containers.

The choice of container depends on what exactly you want to do with the objects.

查看更多
神经病院院长
4楼-- · 2020-02-15 06:04

I'd use an ExecutorService to manage my threads as a pool and put the Futures I am given when adding my Threads to the pool in some form of Collection.

In this way you can manage all of the threads as one unit via the Executor and track individual threads through their Future.

Edit in response to yours

You can use the shutdownNow method of the ExecutorService to abort all running threads.

Example (not a solution to your problem but covers most benefits of using Executors):

// Thread pool for the collectors.
ExecutorService threads = Executors.newFixedThreadPool(MAX_THREADS);
...
// Futures of all collectors running in the pool.
ConcurrentLinkedQueue<Future> collectors = new ConcurrentLinkedQueue<Future>();
...
// Make my Callable.
Callable<Void> c = new FileListCollector(path, recurse, filter);
// Start it up and keep track of it so we can find out when it has finished.
collectors.add(threads.submit(c));
...

// Called when nothing in queue.
private void checkForFinished() {
  // Count the running threads.
  int runningThreads = 0;
  try {
    // Track dead ones to remove.
    List<Future> deadThreads = new LinkedList<Future>();
    // Walk all collectors.
    for (Future f : collectors) {
      // I've seen f being null once. No idea how.
      if (f != null) {
        // If it's not done then it's running.
        if (!f.isDone()) {
          // Count it.
          runningThreads += 1;
        } else {
          // Mark for deletion.
          deadThreads.add(f);
        }
      }
    }
    // Clear dead threads - just to be tidy.
    collectors.removeAll(deadThreads);
  } catch (ConcurrentModificationException cme) {
    // Probably a new thread has been started while I was checking!
    // Therefore almost certainly NOT all finished.
    runningThreads += 1;
  }
  // If no threads are left, we're done.
  if (runningThreads == 0) {
    // Finished! Close everything down.
    close();
  }
}

// Close down the whole system.
public void close() {
  // Use the fileQueue state to indicate closed.
  if (!fileQueue.isClosed()) {
    // Close the queue ... unblocking all collectors (I hope).
    fileQueue.close();
    // Shut them down agressively as this may be called by user prematurely as well as by me.
    threads.shutdownNow();
    // Wait until all is done.
    boolean terminated = false;
    do {
      try {
        // Wait up to 1 second for termination.
        terminated = threads.awaitTermination(1, TimeUnit.SECONDS);
      } catch (InterruptedException ex) {
        // Ignore the interrupt! If I exit here we will probably leak.
      }
    } while (!terminated);
    log("! All done");
  }
}
查看更多
Melony?
5楼-- · 2020-02-15 06:14

I would just use a thread pool, and more specifically a thread pool executor. That would maintain a cache of threads for you to use, although you won't be able to access specific threads on demand.

查看更多
爷、活的狠高调
6楼-- · 2020-02-15 06:14

Synchronize your writes, and you're good. There isn't much more to it unless you're doing something special or unusual. You can do this by modifying your code to only allow one thread the ability to write at a time, or you can have just one thread do all the writing.

A "native" class won't offer you more reliability necessarily, if you cover your bases with multiple write access.

I'm not sure how old this trail is, but covers the basics synchronization, multiple thread access, and a few other things.

查看更多
登录 后发表回答