2015-02-10 298 views
0

我想知道我对下面的代码示例是正确的。 我在java中有两个线程。 Thread_W and Thread_R 两者都可以访问Queue<String> queueJava多线程写入和读取

在Thread_W中有一个名为put的方法。

private void put(String email){ 
queue.offer(email); 
} 

并且在Thread_R中有一个名为get AND的方法,它在Thread_R启动时被调用一次。

public void get(){ 
while(true) 
{ 
    if(!queue.isEmpty()) 
    { 
     String to = queue.poll(); 
     //thread will consume some time here ...may be 5-10 seconds. 
    } 
} 
} 

所以在Thread_W方法put将称为更有效地通过在Thread_W.may甲其他方法是在while循环。

如果我在我的Java项目中使用此代码,Thread_R会丢失放入队列的任何电子邮件吗?

P.S.我真的需要一个缓冲区

+3

看看java的并发性。你需要一个线程安全的队列。 – vikingsteve 2015-02-10 19:25:48

+0

为什么阅读主题“失去任何电子邮件”? – Zhedar 2015-02-10 19:25:56

+0

您应该使用锁定来防止同时发生读写。它的要点是写入过程正在写入,所以它锁定队列。读取进程尝试访问队列,但必须等待写入完成.. – 2015-02-10 19:26:26

回答

0

您应该使用Blocking Queue接口的实现,因为那些接口是线程安全的。

该界面提供了方法put()take(),这些方法会一直执行,直到它们被执行。这样,如果队列已满,读取线程不会占用大量CPU周期,写入线程也不会写入。
您当前的忙等待

while(true) 
{ 
    if(!queue.isEmpty()) 
    { 
     //... 
    } 
} 

是不是很有效。最好使用阻塞方法调用,所以如果队列为空(或满),则不需要检查。
如果您的写入线程比读取线程的速度快put() wait的for space to become available,您也无法溢出队列的缓冲区。

请记住,您可以随时手动为队列预留更大的缓冲区,方法是事先在其中设置capicitiy,例如, ArrayBlockingQueue(int capacity)

+0

但我需要一个大的缓冲区size.unlimited。因为写入缓冲区会很快发生。只有读取速度会很慢 – 2015-02-10 19:34:37

+0

'put()'会阻塞写入线程,直到缓冲区中有空间。根据文档:'将指定的元素插入到该队列中,等待空间变得可用。'更大的缓冲区不是最好的解决方案。 – Zhedar 2015-02-10 19:36:20

+0

put()将阻止写入线程....这是问题.... 我需要一个缓冲区解决方案...就像YouTube加载所有视频然后播放 – 2015-02-10 19:38:41

0

如果你想使用一个无限制的并发队列,我建议看看Deque的线程安全实现,例如LinkedBlockingDequeLinkedBlockingDeque可以是无限的,如果队列为空,则take()将阻塞调用线程。如果使用java.util.concurent包中的类,则不必担心同步。