【问题标题】:Create a simple queue with Java threads使用 Java 线程创建一个简单的队列
【发布时间】:2012-04-12 13:29:14
【问题描述】:

我正在尝试使用 Java Thread 创建一个简单的队列,该队列将允许一个循环,例如一个具有 10 次迭代的 for 循环,一次迭代 n (

这里有一个更好的方式来说明我的问题:

for (int i = 1; i <= 10; i++) {
    new Thread ( do_some_work() );

    if ( no_available_threads ) {
        wait_until_available_threads();
    }
}

do_some_work() {
    // do something that takes a long time
}

基本上我想做的是这个的副本:Thread and Queue

我怎样才能以最轻松的方式实现这一目标?

【问题讨论】:

标签: java multithreading queue


【解决方案1】:

我会使用 Java 5 Executors 而不是自己滚动。类似于以下内容:

ExecutorService service = Executors.newFixedThreadPool(10);
// now submit our jobs
service.submit(new Runnable() {
    public void run() {
        do_some_work();
    }
});
// you can submit any number of jobs and the 10 threads will work on them
// in order
...
// when no more to submit, call shutdown, submitted jobs will continue to run
service.shutdown();
// now wait for the jobs to finish
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);

【讨论】:

    【解决方案2】:

    按照其他人的建议使用执行器。但是,如果您想要自己动手做的乐趣,请尝试这样的事情。 (请注意。我是在记事本中编写的,即使我做对了所有其他事情,您也需​​要捕捉一些异常。记事本不善于捕捉编码错误。)这更像是一个概念,而不是任何事情的实际解决方案,但这个想法可能很有用。

    private ConcurrentLinkedQueue<MyThread>  tQueue =
                 new ConcurrentLinkedQueue<MyThread>();
    
    class MyThread  extends Thread  {
        public Runnable  doSomething;
    
        public void run()  {
            // Do the real work.
            doSomething();
            // Clean up and make MyThread available again.
            tQueue.add( mythread );
            // Might be able to avoid this synch with clever code.
            // (Don't synch if you know no one's waiting.)
            // (But do that later.  Much later.)
            synchronized (tQueue)  {
                // Tell them the queue is no longer empty.
                tQueue.notifyAll();
            }
        }
    }
    

    其他地方:

    // Put ten MyThreads in tQueue.
    for (int i = 0; i < 10; i++)  tQueue.add( new MyThread() );
    
    // Main Loop.  Runs ten threads endlessly.
    for (;;)  {
        MyThread  t = tQueue.poll();
        if (t == null)  {
            // Queue empty.  Sleep till someone tells us it's not.
            do  {
                // There's a try-catch combo missing here.
                synchonized( tQueue )  { tQueue.wait() };
                t = tQueue.poll();
            }  while (t == null)  break;  // Watch for fake alert!
        }
        t.doSomething = do_some_work;
        t.start();
    }
    

    另外,请注意 ConcurrentLinkedQueue 的巧妙使用。您可以使用 ArrayList 或 LinkedList 之类的其他东西,但您需要同步它们。

    【讨论】:

    • 你在使用 ConcurrentLinkedQueue,为什么要同步它?
    【解决方案3】:

    参见 java.util.concurrent,尤其是 Executors 和 ExecutorService

    【讨论】:

      【解决方案4】:

      板条箱Logger.class

      public class Logger extends Thread {
          List<String> queue = new ArrayList<String>();
          private final int MAX_QUEUE_SIZE = 20;
          private final int MAX_THREAD_COUNT = 10;
      
          @Override
          public void start() {
              super.start();
              Runnable task = new Runnable() {
                  @Override
                  public void run() {
                      while (true) {
                          String message = pullMessage();
                          Log.d(Thread.currentThread().getName(), message);
                          // Do another processing
                      }
                  }
              };
              // Create a Group of Threads for processing
              for (int i = 0; i < MAX_THREAD_COUNT; i++) {
                  new Thread(task).start();
              }
          }
      
          // Pulls a message from the queue
          // Only returns when a new message is retrieves
          // from the queue.
          private synchronized String pullMessage() {
              while (queue.isEmpty()) {
                  try {
                      wait();
                  } catch (InterruptedException e) {
                  }
              }
              return queue.remove(0);
          }
      
          // Push a new message to the tail of the queue if
          // the queue has available positions
          public synchronized void pushMessage(String logMsg) {
              if (queue.size() < MAX_QUEUE_SIZE) {
                  queue.add(logMsg);
                  notifyAll();
              }
      
          }
      }
      

      然后在你的主类中插入下面的代码:

      Logger logger =new Logger();
      logger.start();
      for ( int i=0; i< 10 ; i++) {
          logger.pushMessage(" DATE : "+"Log Message #"+i);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-24
        • 2012-10-13
        • 2013-07-19
        相关资源
        最近更新 更多