【问题标题】:Java POJO: strategies for handling a queue of request objects to a serverJava POJO:处理对服务器的请求对象队列的策略
【发布时间】:2011-04-11 23:11:51
【问题描述】:

现在,在决定处理发送到服务器的请求对象的最佳方式时,我感到很困惑。换句话说,我在我的应用程序中有跟踪请求对象,例如印象和点击跟踪。负载非常低的简单请求。在我的应用程序中的某些地方,需要跟踪的所述对象同时出现在彼此旁边(我必须跟踪最多三个并发对象),因此每次所述对象可见时,例如,我必须创建一个跟踪请求他们每个人的对象。

现在我已经知道我可以轻松地创建一个单例队列线程,将这些对象添加到一个向量中,我的线程要么在主循环中处理它们,要么在队列上调用等待,直到我们有对象要处理。虽然这听起来像是一个明确的解决方案,但队列可能会累积成几十个,这有时会很麻烦,因为它为每个请求建立一个连接,因此它不会同时运行。

我的想法是创建一个线程池,它允许我通过信号量创建两个并发连接并处理包含我的跟踪事件请求的线程对象。换句话说,我想创建一个函数来创建一个新的线程对象并将其添加到 Vector 中,其中线程池将遍历线程集并一次处理两个线程。我知道我可以创建一个添加对象的函数,如下所示:

public boolean addThread(Runnable r){
synchronized(_queue){
    while(!dead){
       _queue.addElement(r);
       //TODO: How would I notify my thread pool object to iterate through the list to process the queue? Do I call notify on the queue object, but that would only work on a thread right??
       return true
    }
    return false;
}

我想知道线程本身将如何执行。在将线程添加到列表后,如何编写一个执行线程池的函数?此外,由于信号量会在第二次连接后阻塞,这会锁定我的应用程序直到有一个打开的插槽,还是会在循环遍历列表时锁定在线程池对象中?

与往常一样,由于我的目标是 J2ME/Blackberry 环境,因此仅接受 1.5 之前的答案,因此不接受泛型或 Concurrent 包中的任何类。

编辑:所以我认为这或多或少应该是这样的:

class MyThreadPool extends Thread{

  private final Vector _queue = new Vector();
  private CappedSemaphore _sem;
  public MyWaitingThread (){
      _sem = new CappedSemaphore(2);
      this.start();
  }
  public void run(){
     while(!dead){
        Runnable r = null;
        synchronized(_queue){
          if(_queue.isEmpty()){
            _queue.wait();
          } else {
            r = _queue.elementAt(0);
            _queue.removeElement(0);
          }
       }
       if(r != null){
          _sem.take();
          r.run();
          _sem.release();
       }
    }
 }
 public boolean addThread(Runnable r){
   synchronized(_queue){
   if(!dead){
     _queue.addElement(r);
     _queue.notifyAll();
     return true
   }
   return false;
 }
}

【问题讨论】:

  • 您不应该这么快打折 Java 5 并发包。 Java 5 中没有什么神奇的功能可以实现它,其中大部分是由 Doug Lea 在 Java 1.4 中完成的,它只是在 Java 5 中标准化。backport-jsr166.sourceforge.net/index.php 是 j.u.concurrent 的后向移植。
  • 由于 Semaphore 的实现实现了 Serializable(MIDP/CLDC 中不存在的东西),我不能简单地导入类,因此我的目标是 POJO解决方案,可以仅在原始对象和准系统对象上完成。
  • 一想,一切看起来都很好。如果您确保始终启动两个线程,则不需要信号量。您将并发限制在线程局部性,因此您不必担心另一个同步原语。否则你应该工作。
  • 我只是好奇如何在不使用信号量的情况下做到这一点,因为它看起来像它的编写方式,它只会连续处理它们,除非我遗漏了什么。

标签: java multithreading queue pool pojo


【解决方案1】:

您想要做的是,在线程端让每个线程在队列中等待。例如

class MyWaitingThread extends Thread{

   private final Queue _queue;
   public MyWaitingThread (Queue _queue){
      this._queue = _queue;
   }
   public void run(){
      while(true){
       Runnable r = null;
       synchronized(_queue){
            if(_queue.isEmpty())
                _queue.wait();
            else
               r = queue.pop();
        }
      if(r != null) r.run();
      }
   }
}

在你的其他逻辑中,它看起来像:

public void addThread(Runnable r){
     if(!dead){
       synchronized(_queue){
         _queue.addElement(r);
         _queue.notifyAll();
       }
     }
}

_queue.notifyAll 将唤醒在 _queue 实例上等待的所有线程。另外,请注意我将while(!dead) 移出同步块并将其更改为if(!dead)。我可以想象保持原来的方式它不会像你希望的那样工作。

【讨论】:

  • 我想我忘了编辑该函数以返回一个布尔值,这样它就可以逃脱 while 循环,因为 Sun 在 J2ME 线程教程中的简单队列示例中就是这样做的。我现在就去修。另外,我不能使用 Queue 对象,因为它不适用于 J2ME,但我明白你的意思。我必须先调用 elementAt,然后再调用 removeElement,以便从 Vector 队列中取出对象。
猜你喜欢
  • 2018-01-07
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 1970-01-01
  • 2020-11-29
  • 2017-11-13
相关资源
最近更新 更多