Learning through Mistakes: Java's Three BlockingQueues

Recently, my team of programmers and I discovered a minor fault with the application request mechanism. After a few checks, we found the root cause of the fault to be caused by the use of BlockingQueue. Seeing as there are several common BlockingQueues used in Java, such as ArrayBlockingQueue, LinkedBlockingQueue, and SynchronousQueue, I thought it would be useful for other programmers to write a quick article based on the issue we found and how we solved it.


The Fault & Diagnosis

The symptoms of the fault were simple, yet problematic - the thread pool for application processing requests was full so additional requests could not be processed. After dumping the threads we saw the stack of threads were blocked in the log writing area. Thread stacks blocked in the log writing area is not a new problem, but previously we thought this was the result of something else. Therefore, based on past experiences, we assumed the problem was not in the log writing area.

 

After using many troubleshooting approaches and getting frustrated after not finding the root cause of the issue, we went back to have a look at the source code to try and get some clues as to what was causing the issue. We discovered that the code had a log lock in it. From this log lock, we could see from the thread stack that there was a block in ArrayBlockingQueue.put. After further inspection, we found that it was a 1024 length BlockingQueue. What this means is if this queue has 1024 objects, a subsequent Put Request will be blocked.

 

The programmer who wrote the code had considered that if and when the BlockingQueue was full, the data should be processed. Here is the code in question: 

 

if (blockingQueue.remainingCapacity() < 1) { //todo } blockingQueue.put

Here, there are two main parts to the problem:

1. A complete judgment goes directly to 'put', rather than 'else'.

2. After the queue is full, the processing logic is still //todo...

 

The above code shows this particular programmer's lack of familiarity with the BlockingQueue interface. To achieve this result you do not need to first perform this judgment. A better way would be to use blockingQueue.offer. If it returns as ‘false' then you can implement the relevant exception processing.

 

Types of BlockingQueues

A BlockingQueue is a commonly used data structure in production/consumer mode. The most commonly used types are ArrayBlockingQueue, LinkedBlockingQueue, and SynchronousQueue.

The main difference between ArrayBlockingQueue and LinkedBlockingQueue lies in the objects placed in the queue. One is used for arrays and the other for link tables. The other differences are also given in the code notes:

Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.

 

SynchronousQueue is a special BlockingQueue. It is used during offers. If no other thread is currently performing take or poll, the offer will fail. During take, if no other thread is performing offer concurrently, it will also fail. This special mode is well suited for a queue with high response requirements and threads from a non-fixed thread pool.

Problem Summary

For online business scenarios, there must be a timeout mechanism in all areas where concurrency and external access are blocked. I don't know how many times I have seen a lack of a timeout mechanism being the root cause to serious online business faults.
Online businesses emphasize the fast processing and completion of a request. Therefore fail fast is the most important principle in online business system designs and code programming. According to this principle, the most obvious mistake in the code above is the use of put, rather than offer with a timeout mechanism. Or, you could say that, for unimportant scenarios, offer should be directly used, and a result of ‘false' will directly cause the throwing or recording of an exception.

Concerning the BlockingQueue scenario, in addition to a timeout mechanism, the queue length must be limited. Otherwise, Integer. MAX_VALUE is used by default. In this case, if the code has a bug, the memory will be suspended.

When talking about BlockingQueue, we should also mention the most used area of the BlockingQueue - the thread pool. Java's

 

ThreadPoolExecutor has the BlockingQueue parameter. If ArrayBlockingQueue or LinkedBlockingQueue is used here and the thread pool's coreSize and poolSize are different, then, after the coreSize threads are occupied, the thread pool will first send an offer to the BlockingQueue. If successful, the process ends.
This scenario however does not always suit the needs of online businesses.

 

Online businesses operate in a fast paced environment and need fast processing as opposed to placing requests in queues. In fact, it is best for online businesses if requests are not stacked in a queue at all. This sort of online business structure can easily lead to an avalanche and directly rejecting requests that are beyond the processing capabilities of the system and throwing out an error message instead is a relatively simple yet good method. However it is a limitation mechanism.

 

Remember when writing highly-concurrent and distributed code that it is not all just about system design, it’s important to pay attention to all the small details in your code. That’s how you can avoid problems like the one mentioned above.

时间: 2024-10-19 12:36:41

Learning through Mistakes: Java's Three BlockingQueues的相关文章

Top 10 Mistakes Java Developers Make(转)

    文章列出了Java开发者最常犯的是个错误.   1.将数组转换为ArrayList 为了将数组转换为ArrayList,开发者经常会这样做: ? 1 List<String> list = Arrays.asList(arr); Arrays.asList()会返回一个ArrayList,但这个ArrayList是Arrays的私有静态类,不是java.util.ArrayList.java.util.Arrays.ArrayList有set(), get(), contains()方

25个Java机器学习工具和库

1. Weka集成了数据挖掘工作的机器学习算法.这些算法可以直接应用于一个数据集上或者你可以自己编写代码来调用.Weka包括一系列的工具,如数据预处理.分类.回归.聚类.关联规则以及可视化. 2.Massive Online Analysis(MOA)是一个面向数据流挖掘的流行开源框架,有着非常活跃的成长社区.它包括一系列的机器学习算法(分类.回归.聚类.异常检测.概念漂移检测和推荐系统)和评估工具.关联了WEKA项目,MOA也是用Java编写的,其扩展性更强. 3.MEKA项目提供了一个面向多

25 个 Java 机器学习工具和库

本列表总结了25个Java机器学习工具&库: Weka集成了数据挖掘工作的机器学习算法.这些算法可以直接应用于一个数据集上或者你可以自己编写代码来调用.Weka包括一系列的工具,如数据预处理.分类.回归.聚类.关联规则以及可视化. 2.Massive Online Analysis(MOA)是一个面向数据流挖掘的流行开源框架,有着非常活跃的成长社区.它包括一系列的机器学习算法(分类.回归.聚类.异常检测.概念漂移检测和推荐系统)和评估工具.关联了WEKA项目,MOA也是用Java编写的,其扩展性

Java基于高精度整型实现fibonacci数列的方法_java

本文以实例形式讲述了Java基于高精度整型实现fibonacci数列的方法,分享给大家供大家参考之用.具体方法如下: package com.java.learning.recursion; import java.math.*; public class MainClass { public static void main(String args[]){ for(int i = 0; i < 100; i++){ f(i+1); } } public static BigInteger f(

Awesome Machine Learning

  Awesome Machine Learning  A curated list of awesome machine learning frameworks, libraries and software (by language). Inspired by awesome-php. If you want to contribute to this list (please do), send me a pull request or contact me @josephmisiti A

十步完全理解SQL(转)

本文由 伯乐在线 - 水果泡腾片 翻译.未经许可,禁止转载!英文出处: Lukas Eder .欢迎加入翻译组. 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语言.甚至是函数语言(尽管有些人认为 SQL 语言也是一种函数式语言). 我们每天都在写 SQL 并且应用在开源软件 jOOQ 中.于是我想把 SQL 之美介绍给那些仍然对它头疼不已的朋友,所以本文是为了以下读者而特地编写的: 1. 在工作中会用到 SQL

简单十步让你全面理解SQL

很多程序员认为SQL是一头难以驯服的野兽.它是为数不多的声明性语言之一,也因为这样,其展示了完全不同于其他的表现形式.命令式语言. 面向对象语言甚至函数式编程语言(虽然有些人觉得SQL 还是有些类似功能). 我每天都写SQL,我的开源软件JOOQ中也包含SQL.因此我觉得有必要为还在为此苦苦挣扎的你呈现SQL的优美!下面的教程面向于: 已经使用过但没有完全理解SQL的读者 已经差不多了解SQL但从未真正考虑过它的语法的读者 想要指导他人学习SQL的读者 本教程将重点介绍SELECT 语句.其他

Java NIO Chapter1 Learning Tips

1.java.io效率低的原因But in most cases, Java applications have not truly been I/O bound in the sense that the operating system couldn't shuttle data fast enough to keep them busy. Instead, the JVMs have not been doing I/O efficiently. There's an impedance

Java Learning Path (一)、工具篇

一. JDK (Java Development Kit) JDK是整个Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库(rt.jar).不论什么Java应用服务器实质都是内置了某个版本的JDK.因此掌握JDK是学好Java的第一步.最主流的JDK是Sun公司发布的JDK,除了Sun之外,还有很多公司和组织都开发了自己的JDK,例如IBM公司开发的JDK,BEA公司的Jrocket,还有GNU组织开发的JDK等等.其中