In the work and interview, encountered a lot of multithreading problems. Here I summarize, I hope to help you. This article is basically a list of counterexamples, some of them low-level but common.

Of course, it’s also great for a job interview.

Let’s start with 10.

Let me give you a grade

Create a thread pool

Symptom: System resources are exhausted and processes die.

Cause: A thread pool is new each time a method is executed.

Solution: Share a thread pool.

Death Rating: 5 stars

Brain damage rating: five stars

void doJob(){ ThreadPoolExecutor exe = new ThreadPoolExecutor(...) ; exe.submit(newRunnable() {... })}Copy the code

Two, lock leakage

Symptom: A thread has been holding a lock without releasing it, causing lock leakage.

Cause: The UNLOCK function is not executed due to an unknown exception or logic.

Solution: Always place unlock in finally.

Death Rating: 3 stars

Brain damage Rating: four stars

private final Lock lock = new ReentrantLock();
void doJob(){
    try{
        lock.lock();
        //do. sth
        lock.unlock();
    }catch(Exception e){
    }
}
Copy the code

Forget to synchronize variables

Phenomenon: under a certain condition, throw IllegalMonitorStateException.

Cause: Call wait or notify, forget synchronized, or synchronize incorrect variables.

Solution: Before calling these functions, synchronize them with the sync keyword.

Death Rating: 2 stars

Brain damage Rating: four stars

Object condition = new Object();

condition.wait();
Copy the code

4. HashMap is an infinite loop

Symptom: High CPU usage, an infinite loop, using jStack to check is blocked on the GET method.

Reason: Under certain conditions, loop chains are formed when rehashing. Some GET requests go to this ring.

Solution: In multi-threaded environments, use ConcurrentHashMap and don’t hesitate.

Death Rating: 4 stars

Brain damage Rating: four stars

5. Reassign synchronized variables

Symptom: Synchronization cannot be achieved and results are incorrect.

Cause: Reassignment of non-basic types changes the direction of the lock. Different threads may hold different locks.

Solution: Declare the lock object to be final.

Death Rating: 4 stars

Brain damage Rating: three stars

List listeners = new ArrayList();

void add(Listener listener, boolean upsert){
    synchronized(listeners){
        List results = new ArrayList();
        for(Listener ler:listeners){ ... } listeners = results; }}Copy the code

The thread loop does not catch exceptions

Symptom: A thread job cannot continue, terminates without explanation.

Cause: An exception was not caught in the loop, causing the thread to exit.

Solution: Habitually catch all exceptions.

Death Rating: 3 stars

Brain damage Rating: three stars

volatile boolean run = true;
void loop() {while(run){
        //do. sth int a = 1/0; }}Copy the code

Volatile false counters

Symptom: Multithread count results are incorrect.

Reason: Volatile guarantees visibility, not atomicity, and multithreading does not guarantee correctness.

Solution: Use the Atomic class directly.

Death Rating: 3 stars

Brain damage Rating: two stars

volatile count = 0;
void add(){
    ++count;
}
Copy the code

Viii. Scope of error protection

Symptom: Although thread-safe collections are used, synchronization is not achieved.

Reason: Operations modify multiple thread-safe collections, but the operations themselves are not atomic.

Solution: Figure out which logical domain of code to protect.

Death Rating: 3 stars

Brain damage Rating: four stars

private final ConcurrentHashMap<String,Integer> nameToNumber;
private final ConcurrentHashMap<Integer,Salary> numberToSalary;
public int geBonusFor(String name) {
    Integer serialNum = nameToNumber.get(name);
    Salary salary = numberToSalary.get(serialNum);
    return salary.getBonus();
}
Copy the code

Or take the following error code.

Map<String, String> map = Collections.synchronizedMap(new HashMap<String, String>());

if(! map.containsKey("foo"))
    map.put("foo"."bar");
Copy the code

Some old date-handling classes

Phenomenon: using global Calendar, SimpleDateFormat date processing, such as an exception occurs or data is not accurate.

Reason: These two things are not thread-safe, concurrent calls can be problematic.

Solution: Put it in a ThreadLocal, using a thread-safe DateTimeFormatter is recommended.

Death Rating: 3 stars

Brain damage Rating: three stars

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

Date dododo(String str){
    return format(str);
}
Copy the code

Code deadlock

Symptom: Code generates deadlocks and waits for each other.

Reason: The code meets the following four conditions: mutually exclusive; Inalienable; Request and hold; Loop wait.

Solution: Break these four conditions. Or use less syncing.

Death Rating: 2 stars

Brain damage Rating: one star

Here is a simple piece of deadlock code.

final Object lock1 = new Object();
final Object lock2 = new Object();
new Thread(new Runnable() {
    @Override
    public void run() {
        sleep(1000);
        synchronized (lock1) {
            synchronized (lock2) {
            }
        }
    }
}).start();
new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (lock2) {
            sleep(1000);
            synchronized (lock1) {
            }
        }
    }
}).start();
Copy the code

The long variable reads invalid values

Symptom: An unset value is read.

Reason: The long variable reads and writes are not atomic and may read the high 32 bits of one variable and the low 32 bits of another variable.

Solution: Make sure the long and double variables are correct, and add the volatile keyword.

Death Rating: 1 star

Brain damage Level: No star

Extending reading (jdk10) : docs.oracle.com/javase/spec…

Yi? Why are there 11? It must be a multithreaded calculation error.

End

Many Java developers are new to multithreaded development. But even experienced developers can fall into many multithreading pitfalls. Hopefully this article will help you understand the nuances of when your program doesn’t have the right expectations.

The use of multithreading is extremely complex, the probability of error with low-level apis increases exponentially, and the skill requirements are high. Fortunately, the Concurrent package makes this process much easier, but there are still problems with resource planning and synchronization failures. Here is a simple but comprehensive summary: JAVA multithreading scenarios and considerations simple version, but robust code depends on your own practice.

More excellent articles.

“Microservices are not all, just a subset of a specific domain”

Selection and process should be careful, otherwise it will be out of control.

Out of all the monitoring components, there’s always one for you

The Most Common Set of “Vim” Techniques for Linux Production

What are we Developing with Netty?

Linux five-piece or something.

“Linux” Cast Away (1) Preparation”

Linux: Cast Away (2) CPU

Linux cast Away (3) Memory

Linux cast Away (4) I/O

Linux cast Away (5) Network Chapter

Stay tuned for more. Of course, you can also pay attention to the public number.