初始化巨大的库

时间:2015-05-08 09:37:12

标签: java multithreading spring

我在我的应用程序中使用了一个巨大的库。每次请求时我都无法初始化库,所以我将初始化放入配置中。我已经实现了一个队列和一个用于管理队列的服务。加载应用程序后,我有两个实例在运行。问题是它停滞不前,没有回复。

应用程序上下文xml:

<context:component-scan base-package="com.metadata.tripletws.model" />
<context:component-scan base-package="com.metadata.tripletws.service" />

<bean id="wsdService" class="com.metadata.tripletws.service.WsdService" init-method="init"></bean>

<context:component-scan base-package="com.metadata.tripletws.controller" />

服务

@Service
public class WsdService
{
  public final static int MAX_THREADS = 2;
  private WsdQueue queue;

  public void init()
  {
    try {
      queue = new WsdQueue(MAX_THREADS);
      queue.initQueue();
    } catch (InterruptedException ex) {
      Logger.getLogger(WsdService.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

  public WSD getInstance() throws InterruptedException
  {
    return queue.dequeue();
  }

  public void releaseInstance(WSD instance) throws InterruptedException
  {
    queue.enqueue(instance);
  }
}

队列

public class WsdQueue
{
  private List<WSD> queue = new LinkedList();
  private int limit = 5;

  public WsdQueue()
  {
  }

  public WsdQueue(int limit)
  {
    this.limit = limit;
  }

  public void initQueue() throws InterruptedException
  {
    for (int i = 0; i < limit; i++) {
      System.out.println("Initializing WSD nr." + i);
      WSD wsd = new WSD();
      wsd.Initialize();
      this.enqueue(wsd);
    }
  }

  public synchronized void enqueue(WSD item) throws InterruptedException
  {
    while (this.queue.size() == this.limit) {
      wait();
    }
    if (this.queue.size() == 0) {
      notifyAll();
    }
    System.out.println("Adding instance");
    this.queue.add(item);
  }

  public synchronized WSD dequeue() throws InterruptedException
  {
    while (this.queue.size() == 0) {
      wait();
    }
    if (this.queue.size() == this.limit) {
      notifyAll();
    }
    System.out.println("Taking instance");
    return this.queue.remove(0);
  }
}

这是控制器

控制器

@RequestMapping(value = "/api")
public class ApiController
{
  @Autowired
  private WsdService wsdService;


  @RequestMapping(value = "/wordnet", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
  public @ResponseBody
  ArrayList<LexicalWord> getWordsFromSentence(@RequestBody String sentence)
  {
    ArrayList<LexicalWord> results = new ArrayList<>();

    try {
      WSD wsdInstance = wsdService.getInstance();
      List<CWSDResult> list = wsdInstance.AnanlyseSentenceToList(sentence);
      for (CWSDResult res : list) {
        if (!res.hasLegalSense) {
          continue;
        }

        String key = getHighestProbableSynsetKey(res);
        if (key != null && res.senses.containsKey(key)) {
          Synset synset = res.senses.get(key);
          if (synset != null) {
            results.add(new LexicalWord(res.token, synset.getLexFileName()));
          }
        }
      }

      wsdService.releaseInstance(wsdInstance);

    } catch (InterruptedException ex) {
      Logger.getLogger(ApiController.class.getName()).log(Level.SEVERE, null, ex);
    }

    return results;
  }

}

这是我第一次排队并使用线程,并且我会提供任何帮助或示例。没有错误,它只是卡住,什么也没做,也没有回复。

EDIT1:

在答案后我改变了代码,但没有运气。仍然卡住了。也许这个问题出在其他地方,但当我发送一个请求时,它就可以了,我得到了回复。

@Component
public class WsdService
{

  public final static int MAX_THREADS = 2;
  private BlockingQueue<WSD> queue;

  public WsdService()
  {
    queue = new ArrayBlockingQueue(MAX_THREADS);
  }

  @PostConstruct
  public void init()
  {
    try {
      for (int i = 0; i < MAX_THREADS; i++) {
        WSD wsd = new WSD();
        wsd.Initialize();
        System.out.println("WSD nr. " + i + " initialized!");
        queue.put(wsd);
      }
    } catch (InterruptedException ex) {
      Logger.getLogger(WsdService.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

  public WSD getInstance() throws InterruptedException
  {
    return queue.take();
  }

  public void releaseInstance(WSD instance) throws InterruptedException
  {
    queue.put(instance);
  }
}

这是新的applicationContext

<context:component-scan base-package="com.metadata.tripletws.model" />
<context:component-scan base-package="com.metadata.tripletws.service" />

<context:component-scan base-package="com.metadata.tripletws.controller" />

所以..经过大量挖掘库我认为不可能在那里使用多线程。无论如何,我在其他服务(NLP)中使用了blockingQueue并且它运行良好(与EDIT1相同,只是变量不同)。谢谢大家的帮助。

谢谢,

米甲

1 个答案:

答案 0 :(得分:1)

So you're essentially trying to make a pool of -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *CellIdentifier = @"CellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(tableView == firstTableView) { //code for first table view [cell.contentView addSubview: someView]; } if(tableview == secondTableView) { //code for secondTableView [cell.contentView addSubview: someView]; } return cell; } s?. You're certain that WSD isn't thread-safe?

You can safely throw your queue in the garbage, and use a correct ready made version of BlockingQueue instead. It might not necessarily solve your actual problem, but it'll be a working version of what you're attempting here.