Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java a';阻塞';队列不符合多线程的目的_Java_Multithreading_Blockingqueue - Fatal编程技术网

Java a';阻塞';队列不符合多线程的目的

Java a';阻塞';队列不符合多线程的目的,java,multithreading,blockingqueue,Java,Multithreading,Blockingqueue,如果队列已满,ArrayBlockingQueue将阻止生产者线程;如果队列为空,ArrayBlockingQueue将阻止消费者线程 这种阻塞的概念是否与多线程的思想背道而驰?如果我有一个“主”线程,让我们假设我想将所有“日志记录”活动委托给另一个线程。因此,基本上在我的主线程中,我创建了一个Runnable来记录输出,并将其放在ArrayBlockingQueue上。这样做的全部目的是让“主”线程立即返回,而不会在昂贵的日志记录操作中浪费任何时间 但是,如果队列已满,主线程将被阻塞,并将等待

如果队列已满,ArrayBlockingQueue将阻止生产者线程;如果队列为空,ArrayBlockingQueue将阻止消费者线程

这种阻塞的概念是否与多线程的思想背道而驰?如果我有一个“主”线程,让我们假设我想将所有“日志记录”活动委托给另一个线程。因此,基本上在我的主线程中,我创建了一个Runnable来记录输出,并将其放在ArrayBlockingQueue上。这样做的全部目的是让“主”线程立即返回,而不会在昂贵的日志记录操作中浪费任何时间


但是,如果队列已满,主线程将被阻塞,并将等待一个可用的位置。那么它对我们有什么帮助呢?

听起来你大概知道为什么要使用
ArrayBlockingQueue
之类的东西在线程之间进行对话

拥有一个阻塞队列可以让您选择在后台工作线程出现问题时执行不同的操作,而不是盲目地向队列添加更多请求。如果队列中有空间,则不存在阻塞

但是,对于您的特定用例,我将使用
ExecutorService
,而不是直接读取/写入队列,这将创建一个后台工作线程池:


阻塞是多线程的一个必要功能。必须阻止才能同步访问数据。它并不违背多线程的目的

我建议在制作人尝试将项目提交到已满队列时引发异常。我相信,有一些方法可以事先测试容量是否已满

这将允许调用代码决定如何处理完整队列


如果处理队列中的项目时的执行顺序不重要,我建议使用线程池(Java中称为ExecutorService)。

您必须选择在队列已满时执行什么。在数组阻塞队列的情况下,选择等待

另一种选择是,如果队列已满,则丢弃新对象;您可以通过以下方式实现这一点


你必须做出权衡。

我认为这是设计师的决定。如果他选择了阻塞模式,ArrayBlockingQueue将为其提供
put
方法。如果设计者不希望阻塞模式ArrayBlockingQueue有
提供的
方法,当队列已满时,该方法将返回false,但他需要决定如何处理Rejected logging事件。

尽管队列没有阻塞,但它会阻塞以向系统引入额外的质量。在这种情况下,它是防止饥饿的


想象一组线程,其中一个线程可以快速生成工作单元。如果允许队列无限增长,“快速生产者”队列可能占据所有生产能力。有时,预防这种副作用比解除所有线程的阻塞更重要 一般来说,您的一个线程的速度不足以应付指定的负载。因此,其他应用程序必须以某种方式减慢速度,以免危及整个应用程序


另一方面,如果负载平衡,队列将不会阻塞。

一个多线程程序是不确定的,因为你不能事先说:n个生产者操作将与m个消费者操作一样长。因此,在任何情况下,n个生产者和m个消费者之间的同步都是必要的


您需要选择队列大小,以便在大多数情况下使活动生产者和消费者的数量最大化。但是java的线程模型不能保证任何使用者都能运行,除非它是唯一未阻塞的线程。(当然,在多核CPU上,使用者很可能会运行)。

这取决于多线程理念的性质。对于我们这些喜欢阻塞队列的人来说,这几乎是完美的。事实上,理想的情况是,除非接收者准备好接收消息,否则根本无法将消息放入队列

所以不,我不认为阻塞队列违背了多线程的目的。事实上,您描述的场景(主线程最终停止)很好地说明了多线程的参与者模型的主要问题;您不知道它是否会死锁/阻塞,也无法对其进行全面测试

相反,想象一个消息深度为零的阻塞队列。为了让系统能够工作,您必须找到一种方法来确保记录器始终能够从主线程接收消息。那是CSP。这可能意味着,在假设的记录器线程中,您必须具有应用程序定义的缓冲(与某些框架开发人员对FIFO深度的最佳猜测相反)、快速I/O子系统、跟上的检查、处理落后的方法等。简言之,它不会让您侥幸逃脱,您必须解决系统性能的各个方面


这当然很难,但这样一来,如果阻塞队列中的消息数量未知,那么您最终得到的系统肯定是正常的,而不是令人怀疑的“可能”

线程争用、线程饥饿和不安全的并发访问都是多线程处理时必须解决的问题。除非明确要求,否则线程不会很好地处理共享资源。您只考虑队列已满的情况。在其他任何情况下,线程都不会阻塞。@Makoto你在说什么?这与问题无关。顺便说一下,阻塞队列是线程安全的。。。查看类
BlockingQueue
已执行“满时丢弃”操作
pool = Executors.newFixedThreadPool(poolSize);
pool.submit(myRunnable);