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.