我在我的应用程序中使用了一个巨大的库。每次请求时我都无法初始化库,所以我将初始化放入配置中。我已经实现了一个队列和一个用于管理队列的服务。加载应用程序后,我有两个实例在运行。问题是它停滞不前,没有回复。
应用程序上下文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相同,只是变量不同)。谢谢大家的帮助。
谢谢,
米甲
答案 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.