2013-04-26 81 views
0

我是新来的多线程,并有线程和锁定在我的程序中的问题。线程和锁定在我的程序

我已经当程序启动时,它执行waitForValuesToBeAdded创建以下

private final ConcurrentLinkedQueue<String> valueQueue = new ConcurrentLinkedQueue<String>(); 
private final Object lock = new Lock(); 
private ProcessValue processor = new ProcessValues(); 

public void addValue(String value){ 
     synchronized (lock) { 
     valueQueue.add(value); 
     lock.notify(); 
    } 
} 

public void waitForValuesToBeAdded(){ 
     synchronized (lock) { 
     lock.wait(); 
     executeValues(); 
    } 
} 

public void executeValues(){ 
     synchronized (lock) { 
     processor.processValues(); 
     valueQueue.clear(); 
     lock.notify() 
    } 
} 

代码简化我的问题。顾名思义,这只是等待将值添加到队列中。当值被添加时,我们不再wait,所以executeValues()被调用。

当执行processor.processValues()时,我不希望将值添加到队列(valueQueue.add(value))。我需要他们等到processValues()完成。 我想如果我使用同步块它会阻止插入,但是当我添加另一个值,而processValue执行一切都挂起。

我在程序中遗漏了什么吗?

+0

同步块的目的是为了防止两个呼叫者从在同一时间进入同步码码块。第二个呼叫者将被阻止,直到第一个呼叫者退出该块。这可以防止第二个调用方破坏第一个调用者读取或写入的状态(变量)。没有这种锁定,并发收集是安全的;如果你迫使其他呼叫者等待,你需要一个'ConcurrentLinkedQueue'用于什么? – 2013-04-26 18:07:25

+0

你能向我们展示一些行动吗?上述方法称为哪里? – dcernahoschi 2013-04-26 18:23:20

+1

如果队列一次只保存一个对象,则可能需要使用[SynchronousQueue](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/SynchronousQueue。 HTML)而不是 – 2013-04-26 18:25:16

回答

0

尝试使用jvisualvm查看线程被阻塞的位置。你可以做一个“线程转储”来分析这一点。

0

重写如下:

private final ConcurrentLinkedQueue<String> valueQueue = new ConcurrentLinkedQueue<String>(); 
private final Object lock = new Lock(); 
private ProcessValue processor = new ProcessValues(); 

public void addValue(String value) { 
    synchronized (lock) { 
     valueQueue.add(value); 
     lock.notifyAll(); 
    } 
} 

public void waitForValuesToBeAdded() throws InterruptedException { 
    synchronized (lock) { 
     while (valueQueue.size() == 0) { 
      lock.wait(); 
     } 
     executeValues(); 
    } 
} 

public void executeValues() { 
    synchronized (lock) { 
     processor.processValues(); 
     valueQueue.clear(); 
     lock.notifyAll() 
    } 
}