There was a recent failure that took a long time to troubleshoot. Looking back at the whole troubleshooting process, empiricism played a bad role, which directly led to a very long troubleshooting time. The root cause of this failure was that BlockingQueue was faulty. By the way, there are several blockingQueues commonly used in Java: ArrayBlockingQueue, LinkedBlockingQueue, and SynchronousQueue.

When failure phenomenon is application processing request thread pool is full, the result in the request processing and then dump the thread, the thread is doing, the results found that the threads are Block in writing log, there have been many times before, to see is a pile of Block a thread dump in writing log, but often it is caused by other reasons, So this time is also according to such experience, that it is certainly not the problem of writing log this place, so all kinds of investigation… After a long time, I looked back and realized that the place where the log lock was held was code written by one of my own people. After I got the log lock, I looked at the thread stack and saw that the block was in arrayBlockingQueue.put. It turns out that the BlockingQueue is 1024 in length, which means that if the Queue is filled with 1024 objects, the put must be blocked. And if you look at the code, you can see that the person who wrote the code thought that the BlockingQueue should be full. The code reads: If (blockingQueue. RemainingCapacity () < 1) {/ / todo} blockingQueue. Put two miserable questions here, one is that if judgment or go directly to the put, rather than the else, //todo… In addition, I think this code also shows that students are not familiar with the interface of BlockingQueue. To achieve this effect, it is better to use BlockingQueue. Offer, return false and then do the corresponding exception handling.

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

ArrayBlockingQeue/LinkedBlockingQueue the biggest difference lies in store Queue objects in the way, is an array, a linked list, also wrote about the difference in code comments: Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.

SynchronousQueue is a special BlockingQueue that fails if no other thread is taking or polling at offer time. A take will fail if no other thread happens to be concurrent with the offer. This particular pattern is ideal for queues that require a high response and have threads that exit from a variable thread pool.

For online business scenarios, concurrent, all external access block where a truth is must have the timeout mechanism, I don’t know how many times because there is no overtime caused serious fault online business, online business is the most stressed is fast to get rid of a request, so the fail is fast online business system design, One of the most important rules of code writing, the least obvious mistake code can make is to use put instead of offer with a timeout mechanism, or if it’s not important, just use offer at all.

In the BlockingQueue scenario, in addition to the timeout mechanism, the queue length must be limited, otherwise the default is integer.max_value, in case the code is bugged, the memory will be ruined.

When it comes to BlockingQueue, it’s worth mentioning where BlockingQueue is used the most: Thread pool. Java’s ThreadPoolExecutor has an argument called BlockingQueue. If you use ArrayBlockingQueue or LinkedBlockingQueue, If the coreSize thread pool is not the same as the poolSize thread pool, the thread pool will first make an offer to the BlockingQueue after the coreSize thread is full. If the thread pool succeeds, the offer will end. Instead of queuing first, and in fact, the online business is best not to let the request pile up in the queue, online business can easily trigger an avalanche, directly reject the error beyond the processing capacity is relatively good practice, as for the previous page queuing what this is ok, that is another kind of traffic limiting mechanism.

So when writing highly concurrent, distributed code, in addition to the system design, the code details are very, very important.

Reprinted from:
http://hellojava.info/

By Ali Bixuan