Hello everyone, I am Wolf King, a programmer who loves playing ball

I’ve spent some time putting together a list of multi-threaded, concurrent interview questions. It’s not a lot, but it’s useful to look at them occasionally.

Don’t say a word, just turn it on!

01 What is a thread?

Thread is the smallest unit that the operating system can schedule operations. It is contained in the process and is the actual operating unit in the process. It can use multi-threading to speed up operations.

What is thread-safe and thread-unsafe?

Thread safety:

When multithreading access, the locking mechanism is used. When one thread accesses a certain data of the class, it is protected and other threads cannot access it until the thread finishes reading and other threads can use it. There will be no data inconsistencies or data contamination. Vector is thread-safe using a synchronous approach, whereas ArrayList, like it, is not thread-safe.

Thread unsafe:

Without data access protection, it is possible for multiple threads to change data successively, resulting in dirty data. Thread safety problems are caused by global variables and static variables. If there are only reads and no writes on a global variable or static variable per thread, the global variable is generally thread-safe. If you have multiple threads performing write operations at the same time, you generally need to consider thread synchronization, otherwise it may affect thread safety.

What is spinlock?

Spin-lock is a low-level synchronization mechanism in the SMP architecture.

When thread A wants to acquire A spin lock that is held by another thread lock, thread A spins in A loop to check if the lock is available.

Spin-locks need to be noted:

  1. Since spinning does not release the CPU, the thread holding the spin lock should release the spin lock as soon as possible, otherwise the thread waiting for the spin lock will keep spinning there, wasting CPU time.
  2. The thread holding the spin lock should release the spin lock before sleep so that other threads can acquire the spin lock.

Current JVM implementations use up CPU for spin, and if the doNotify method is not called for a long time, doWait will spin all the time, which can be too CPU consuming.

Spin-lock is suitable for the situation where the user holds the lock for a short time. In this case, spin-lock is more efficient.

Spin-locking is a mechanism that works quite well with multiple processors, but is largely unusable in single-processor, non-preemptive systems.

04 What is CAS?

  1. CAS (compare and swap) abbreviation, Chinese translation to compare and exchange.
  2. CAS directly calls THE CPU’s CMPXCHG instruction using Java Native Interface (JNI) without using the JVM.
  3. Using CAS instruction of CPU, at the same time with the help of JNI to complete Java non-blocking algorithm, realize atomic operation. Other atomic operations are performed using similar properties.
  4. The entire java.util.Concurrent is built on TOP of CAS, so J.U.C offers a significant performance boost over synchronized blocking algorithms.
  5. CAS is an optimistic locking technique. When multiple threads attempt to update the same variable using CAS, only one thread can update the value of the variable. However, all other threads fail.
  1. Using CAS can significantly degrade program performance when thread conflicts are severe. CAS is only suitable for use when thread collisions are low.
  2. Synchronized has been improved since jdk1.6. The underlying implementation of synchronized mainly relies on lock-free queues. The basic idea of synchronized is spin-back blocking, which continues to compete for locks after competitive switching, sacrificing fairness slightly, but achieving high throughput. Performance similar to CAS can be achieved with fewer thread collisions; In the case of serious thread conflicts, the performance is much higher than that of CAS.

What are optimism locks and pessimism locks?

  1. Pessimistic locking

Prior to JDK1.5, Java relied on the synchronized keyword, which coordinates access to shared state by using a consistent locking protocol. This ensures that whichever thread holds the lock on shared variables has exclusive access to them. An exclusive lock is a pessimistic lock, so synchronized is a pessimistic lock.

  1. Optimistic locking

Optimistic Locking is actually an idea. Compared with pessimistic locks, optimistic locks assume that data will not cause conflicts in general, so when data is submitted for update, data conflicts will be formally detected. If conflicts are found, the error message will be returned to the user, so that the user can decide what to do. Memcached uses the CAS optimistic locking technique to ensure data consistency.

06 What is AQS?

1, AbstractQueuedSynchronizer AQS for short, is a framework for building locks and synchronization container. In fact, many classes in the Concurrent package are built based on AQS, such as ReentrantLock, Semaphore, CountDownLatch, ReentrantReadWriteLock, FutureTask, etc. AQS addresses many of the details of design when implementing synchronous containers.

2. AQS uses a FIFO queue to represent the thread queuing for the lock. The queue head node is called “sentinel node” or “dumb node”, which is not associated with any thread. The other nodes are associated with wait threads, and each node maintains a waitStatus, waitStatus

What is atomic operation? What atomic classes are available in the Java Concurrency API?

  1. An atomic operation is an operational task unit that is not affected by other operations. Atomic manipulation is a necessary means to avoid data inconsistencies in multithreaded environments.
  2. Int++ is not an atomic operation, so when one thread reads its value and increments by one, another thread may read the previous value, which raises an error.
  3. To solve this problem, it is necessary to ensure that increment operations are atomic, which we could do using synchronization techniques prior to JDK1.5.

To JDK1.5, Java. Util. Concurrent. Atomic package provides an int and long types of classes, they can be automatically guarantee for their operation is atomic and don’t need to use the synchronization.

What is Executors Framework?

Java provides four thread pools through Executors:

NewCachedThreadPool Creates a cacheable thread pool. If the length of the thread pool exceeds the processing requirement, free threads can be recycled, or new threads can be created. NewFixedThreadPool Creates a fixed-length thread pool that controls the maximum number of concurrent threads, and the excess threads wait in the queue. NewScheduledThreadPool Creates a thread pool of fixed length that supports scheduled and periodic task execution. NewSingleThreadExecutor creates a single-threaded thread pool that uses only one worker thread to execute tasks, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority).

What is a blocking queue? How to implement the producer-consumer model using blocking queues?

1. JDK7 provides seven blocking queues. (Also a concurrent container)

ArrayBlockingQueue: A bounded blocking queue composed of array structures. LinkedBlockingQueue: A bounded blocking queue consisting of a linked list structure. PriorityBlockingQueue: An unbounded blocking queue that supports priority sorting. DelayQueue: an unbounded blocking queue implemented using a priority queue. SynchronousQueue: A blocking queue that does not store elements. LinkedTransferQueue: An unbounded blocking queue consisting of a linked list structure. LinkedBlockingDeque: A bidirectional blocking queue consisting of a linked list structure.

2. Concept: a blocking queue is a queue that supports two additional operations on top of the queue.

3. Two additional operations:

3.1. Blocking insertion method: When the queue is full, the queue will block the thread that inserts the element until the queue is full.

3.2 Blocking removal method: When the queue is empty, the thread that obtains the element will wait for the queue to become non-empty.

10 What are Callable and Future?

1. Callable and Future are an interesting pair. We need them when we need to get the results of a thread’s execution. Callable is used to produce results, and Future is used to retrieve results.

The Callable interface uses generics to define its return type. The Executors class provides some useful methods for executing Callable tasks in the thread pool. Because the Callable task is parallel, you must wait for the result it returns. Java. Util. Concurrent. The Future object to solve the problem.

3. A Future object is returned after the Callable task is submitted by the thread pool. It can be used to know the status of the Callable task and get the execution result returned by the Callable. The Future provides a get() method that waits for the Callable to end and retrieves its execution result.

11 What is FutureTask?

1. FutureTask can be used in scenarios where an execution result is retrieved asynchronously or a task is cancelled. By passing a Runnable or Callable task to FutureTask, calling its RUN method or putting it into a thread pool for execution, FutureTask can then get the result of the execution asynchronously externally via FutureTask’s GET method. Therefore, FutureTask is very suitable for time-consuming calculations. The main thread can retrieve the result after completing its task. In addition, FutureTask can ensure that even if the run method is called multiple times, it will only execute a Runnable or Callable task once, or cancel the execution of FutureTask with cancel, etc.

Futuretask can be used to perform multiple tasks and avoid creating multiple machine locks in high concurrency situations.

What are the implementations of synchronous and concurrent containers?

Synchronous container:

1, the main representative have the Vector and the Hashtable, and Collections. SynchronizedXxx, etc.

2. The granularity of the lock is the whole object.

3, the iterator is timely failure, i.e., found in the iterative process has been changed, and will throw ConcurrentModificationException.

Concurrent container:

1. Main representatives include ConcurrentHashMap, CopyOnWriteArrayList, ConcurrentSkipListMap, and ConcurrentSkipListSet.

2. The granularity of locks is decentralized and fine-grained, that is, different locks are used for reading and writing.

3, iterative appliances have weak consistency, namely can tolerate concurrent modification, ConcurrentModificationException.

ConcurrentHashMap uses the segmented lock technology. In a synchronous container, one lock is used for each container. In ConcurrentHashMap, the array of the hash table is divided into several segments and each segment maintains one lock for efficient concurrent access.

What is multithreaded context switching?

1. Multithreading: it refers to the concurrent technology of realizing multiple threads from software or hardware.

2, the benefits of multi-threading:

The use of multithreading can take a long time in the program to the background to deal with tasks, such as pictures, video downloads play the advantages of the multi-core processor, concurrent execution to make the system run faster, more smooth, better user experience

3. Disadvantages of multi-threading:

Large numbers of threads reduce code readability; More threads need more memory space, so attention should be paid to thread safety when multiple threads compete for the same resource.

4, multi-threaded context switch:

The CPU uses the time slice allocation algorithm to execute tasks in a cycle. After the current task executes a time slice, it switches to the next task. However, the state of the previous task is saved before switching, so that the next time you switch back to the task, you can load the state again.

What is the design concept and function of ThreadLocal?

The ThreadLocal class in Java allows us to create variables that can only be read and written by the same thread. Thus, if a piece of code contains a reference to a ThreadLocal variable, even if two threads execute the code at the same time, they cannot access each other’s ThreadLocal variable.

Concept: thread-local variables. In concurrent programming, member variables that are not handled are not thread-safe, and we know that the volatile keyword is not thread-safe. So in one case, we need to satisfy the condition that the variable is the same, but each thread uses the same initial value, that is, a new copy of the same variable. ThreadLocal is useful in this case, for example, for database connections to DAO. We know that DAO is a singleton, so its property Connection is not a thread-safe variable. We need to use it for each thread, and each thread uses its own. In this case, ThreadLocal solves this problem.

Principle: In essence, each thread maintains a map whose key is threadLocal and whose value is the same as the set value. Each thread gets a value from its own variable, so there is no thread safety problem. The state of the ThreadLocal variable does not change at all; it simply acts as a key and provides each thread with an initial value.

Each Thread object maintains a ThreadLocalMap, which can store several ThreadLocal’s.

15 ThreadPool usage and advantages?

ThreadPool advantages:

Reduced the number of creating and destroying threads, each worker thread can be reused, and can perform multiple tasks Can be based on the system capacity, adjust the working line the number of threads in thread pool, prevent because because consumes too much memory, and to exhaust the server (each thread takes about 1 MB of memory, thread to open, the more the greater the consumption of memory, Finally crash)

—— reduces the time spent creating and destroying threads and the overhead of system resources

—— If the thread pool is not used, the system may use up system memory by creating a large number of threads

The next top layer of thread pools in Java is executors, but executors are not strictly a thread pool, but a tool for executing threads. The real thread pool is the ExecutorService.

  1. When the number of threads is less than corePoolSize, a thread is created to execute the task.
  2. If the number of threads is greater than or equal to corePoolSize and the workQueue is not full, it is added to the workQueue
  3. The number of threads is greater than or equal to corePoolSize, and when the workQueue is full, a new task is created to run, and the total number of threads is smaller than maximumPoolSize
  4. Handler rejectedExecution is executed when the number of threads equals maximumPoolSize and the workQueue is full. That’s the rejection strategy.

Other things in the Concurrent package: ArrayBlockingQueue, CountDownLatch, and so on.

ArrayBlockingQueue A bounded blocking queue composed of array structures.

CountDownLatch allows one or more threads to wait for other threads to complete operations. Join is used to make the current executing thread wait for the join thread to finish executing. This works by constantly checking whether the join thread is alive, and if so, making the current thread wait forever.

17 The difference between synchronized and ReentrantLock?

Basic knowledge:

  1. Reentrant lock. A reentrant lock means that the same thread can acquire the same lock multiple times. ReentrantLocksynchronized are reentrant lock.
  2. Interruptible locking. Interruptible lock refers to whether the thread can respond to interrupt when trying to acquire the lock. Synchronized is an uninterruptible lock, while ReentrantLock provides an interrupt function. Fair and unfair locks. A fair lock means that when multiple threads attempt to acquire the same lock at the same time, the lock is acquired in the order that the thread achieved, while a non-fair lock allows the thread to “jump the queue”. Synchronized is an unfair lock, while ReentrantLock’s default implementation is an unfair lock, but it can also be set to a fair lock.
  3. CAS operation (CompareAndSwap). CAS simply compares and swaps. The CAS operation contains three operands — the memory location (V), the expected old value (A), and the new value (B). If the value of the memory location matches the expected original value, the processor automatically updates the location value to the new value. Otherwise, the processor does nothing. In either case, it returns the value of that location before the CAS instruction. CAS effectively says “I think position V should contain the value A; If this value is included, place B in this position; Otherwise, do not change the location, just tell me the current value of the location.”
  4. Synchronized: isynchronized is a built-in Java keyword that provides an exclusive way to lock. Synchronized acquisition and release lock by JVM, users do not need to display the release lock, very convenient. Synchronized, however, has certain limitations:

When a thread attempts to acquire a lock, it will block until the lock is acquired.

If the thread that acquired the lock goes to sleep or blocks, other threads attempting to acquire the lock must wait unless the current thread is abnormal.

  1. ReentrantLock:

ReentrantLock is an API-level mutex provided after JDK 1.5 that requires lock() and unlock() methods in conjunction with a try/finally block.

(If another thread is holding the lock, it will wait for the specified time. During the waiting process, it will return true if the lock is acquired, and false if the wait times out.)

A Synchronized lock is an unfair lock. The default constructor of ReentrantLock is to create an unfair lock. You can use the parameter true to set a fair lock, but the performance of a fair lock is not very good.

18 What does Semaphore do?

A Semaphore is a Semaphore that limits the number of concurrent requests for a block of code

What is the Java Concurrency API Lock interface? What are the advantages over synchronization?

1. The Lock interface provides more extendable locking operations than synchronized methods and synchronized blocks. They allow for more flexible structures that can have radically different properties, and can support conditional objects of multiple related classes.

2, its advantages are:

You can make locks fairer you can make threads respond to interruptions while they’re waiting for locks you can make threads try to acquire locks and return immediately if they’re not available or you can wait a certain amount of time you can acquire and release locks in different order at different ranges

20 Hashtable size() has only one statement “return count”.

1. Only one thread can execute synchronous methods of a fixed class at a time, but for asynchronous methods of a class, multiple threads can access them simultaneously. Thread B could call the size() method to read the current number of elements in the Hashtable. That might not be the latest value. Thread A might have added data, but it didn’t add size++, Thread B has already read the size, so it must be inaccurate for thread B to read the size.

The size() method can be called by thread B only after thread A has finished calling the put method.

21 What is the concurrency of ConcurrentHashMap?

1. How it works (sharding) : it introduces the concept of “segmenting lock”, which can be defined as splitting a large Map into N smaller segments and deciding which HashTable to place the key in according to key.hashcode (). Can provide the same thread-safety, but N times more efficient, 16 times more efficient by default.

2, application: when read > write use, suitable for caching, initialization at the start of the program, can be accessed by multiple threads;

3. Hash conflict:

Summary: The hashCode() method is called in the HashMap to calculate the hashCode. Since two different objects in Java may have the same hashCode, different keys may have the same hashCode, leading to conflicts. Hash conflict resolution: Use a balanced tree instead of a linked list. When the number of elements in the same hash exceeds a certain value, the list switches to the balanced tree

4. Lock free read: ConcurrentHashMap has good concurrency because ConcurrentHashMap uses lock free read and lock write, and uses segment-based locking (not all entries are locked, but some entries are locked).

Count (jdk1.6), which is volatile, is written to main memory each time a variable is volatile. Other processors find that the memory address corresponding to their own cache row has been changed, set their own processor’s cache row to invalid, and force the latest data from the system’s main memory.) , so it can be read without lock.

5. ConcurrentHashMap concurrency is the size of the segment. The default value is 16, which means that up to 16 threads can operate on ConcurrentHashMap at the same time.

22 ReentrantReadWriteLock Read/write lock usage?

1, read and write locks: divided into read locks and write locks, multiple read locks are not mutually exclusive, read locks and write locks mutually exclusive, which is controlled by the JVM itself, you just need to set the corresponding lock.

2. If your code reads only data, which can be read by many people at the same time, but cannot be written at the same time, lock it.

3. If your code modifs data and only one person is writing it and cannot read it at the same time, lock it. In short, read while lock, write while lock!

What is the difference between CyclicBarrier and CountDownLatch?

CyclicBarrier and CountDownLatch are both located under the java.util.concurrent package

\

24 LockSupport?

LockSupport is a lower-level class in the JDK that creates locks and basic thread blocking for other synchronization utility classes. Java and synchronizer frame lock core AQS: AbstractQueuedSynchronizer, is by calling LockSupport. The park () and LockSupport unpark () thread blocking and wake up.

Condition interface and its implementation principle?

In the Java.util.Concurrent package, there are two special utility classes, Condition and ReentrantLock. As anyone who has used it knows, ReentrantLock is an implementation of an exclusive lock provided by the CONCURRENT package in the JDK.

We know that synchronization can cause one thread to block while waiting for a signal, while giving up the lock allows other threads to compete for the lock.

Synchronized implements this wait and wake up using Object’s wait() and notify methods.

But how do you implement wait and notify in Lock? The answer is Condition. The main purpose of learning Condition is to learn the source code of BlockQueue and ConcurrenthashMap in the future, and to further understand ReentrantLock.

What is the interpretation of Fork/Join framework?

1. Fork is the process of dividing a large task into several sub-tasks in parallel.

2. Join means to merge the execution results of these sub-tasks and finally get the result of the large task.

27 What is the difference between wait() and sleep()?

1. The sleep() method is a static method of Thread class, which makes the calling Thread enter the sleep state and give the execution opportunity to other threads. After the sleep time ends, the Thread enters the ready state and compets with other threads for the EXECUTION time of CPU.

Because sleep() is static, it cannot change the lock of an object. When sleep() is called in a synchronized block, the thread goes to sleep, but the lock is not released, and other threads cannot access the object.

Wait () is a method of the Object class. When a thread executes a wait method, it enters the wait pool associated with the Object and releases the lock of the Object, enabling other threads to access the wait pool. NotifyAll and Notify methods are used to wake up the waiting thread.

28 Thread five states (five states, created, ready, running, blocked, and dead)?

Threads typically have five states: created, ready, running, blocked, and dead.

The first is to create state. When a thread object is generated, the object’s start method is not called, which is the thread being created.

The second is readiness. When the start method of a thread object is called, the thread is ready, but the thread scheduler has not set the thread to the current thread. The thread is also in the ready state after it runs, after it comes back from waiting or sleeping. The third is the running state. The thread scheduler sets the thread in the ready state to the current thread, at which point the thread enters the run state and starts running the code in the run function.

The fourth is blocking. A thread is suspended while it is running, usually to wait for a certain time to occur (such as when a resource is ready) before continuing. Methods like sleep,suspend, and wait can all cause threads to block.

The fifth is death. If a thread’s run method finishes or stops, the thread dies. For dead threads, you can no longer use the start method to get them ready.

29 What is the difference between the start() and run() methods?

1, the start() method to start a thread, true implementation of multi-threaded running.

2. If you call run() directly, it is equivalent to calling an ordinary function. If you call run() directly, you must wait for the completion of run() method before executing the following code, so there is only one execution path, and there is no thread characteristic at all. So use the start() method instead of the run() method for multithreaded execution.

30 What is the difference between a Runnable interface and a Callable interface?

The return value of the run() method in the Runnable interface is void, and all it does is execute the code in the run() method;

The Call () method in the Callable interface, which returns a value, is a generic type that can be used in conjunction with Future and FutureTask to retrieve the result of asynchronous execution.

31 What does the volatile keyword do?

Multithreading is mainly about visibility and atomicity. Using volatile to modify variables ensures that they are visible across multiple threads. That is, every time a volatile variable is read, it must be the latest data.

The low-level execution of code is not as simple as the high-level language we see — Java programs. It is executed by Java code — > bytecode — >C/C++ code executes according to bytecode — >C/C++ code is compiled into assembly language — > interacts with hardware circuits. In reality, the JVM may reorder instructions for better performance. Some unexpected problems can occur in multithreading. Using volatile disables semantic reordering, which, of course, reduces code execution efficiency.

32 How do I obtain the thread dump file in Java?

Thread dump is the best way to solve problems such as dead loops, deadlocks, blocking, and slow page opening. A thread stack can be retrieved in two steps:

Access to the thread of pid, can use the JPS command, in Linux environment can also use ps – ef | grep Java

The thread stack can be printed by using the jstack PID command, or by using the kill -3 PID command in Linux

On an additional note, the Thread class provides a getStackTrace() method that can also be used to retrieve the Thread stack. This is an instance method, so it is tied to a specific thread instance, and each time it retrieves the current running stack for that particular thread.

What is the difference between threads and processes?

A process is the basic unit of resource allocation in the system and has an independent memory address space

Thread is the basic unit of CPU independent operation and independent scheduling, no separate address space, independent stack, local variables, registers, program counters and so on.

Process creation costs a lot. Creating virtual address Spaces requires a lot of system resources

Creating threads is cheap, with basically just a kernel object and a stack.

One process cannot directly access another process’s resources. Multiple threads within the same process share the resources of the process.

Process switching cost is high, thread switching cost is low; Interprocess communication cost is high, interthread communication cost is low.

Threads belong to processes and cannot be executed independently. Each process must have at least one thread, called the main thread

34 How many ways (four ways) can threads be implemented?

Inherit the Thread class and override the run method

Implement the Runnable interface, override the run method, implement the Runnable interface implementation class instance object as the Target Thread constructor

Implement the Callable interface to create Thread threads through the FutureTask wrapper

Create a thread from a thread pool

How to use thread pools for high concurrency and short task execution time? How can thread pools be used for businesses with low concurrency and long task execution times? How to use thread pools for concurrent high-throughput businesses with long execution times?

High concurrency and short task execution time: The number of threads in the thread pool can be set to the number of CPU cores +1 to reduce thread context switching.

Services with low concurrency and long task execution time should be distinguished:

  1. If the I/O operation takes a long time, that is, THE I/O intensive task, because I/O operations do not occupy CPU, do not idle all THE CPU, you can increase the number of threads in the thread pool, so that the CPU can process more services
  2. (1) The number of threads in the thread pool should be set to a smaller number to reduce thread context switching

The key to solve this type of task is not the thread pool but the design of the overall architecture. The first step is to see whether some data in these businesses can be cached, and the second step is to increase the number of servers. As for the setting of the thread pool, please refer to (2). Finally, problems with long business execution times may also need to be analyzed to see if tasks can be split and decoupled using middleware.

What happens if the thread pool queue is full when you submit a task?

1. If you use LinkedBlockingQueue (i.e., unbounded queue), continue to add tasks to the blocking queue for execution, because LinkedBlockingQueue can be thought of as an almost infinite queue that holds tasks indefinitely;

2. If you use a bounded queue like ArrayBlockingQueue, the task will be added to the ArrayBlockingQueue first. ArrayBlockingQueue is full, The RejectedExecutionHandler policy is used to handle the full task. The default policy is AbortPolicy.

37 Lock level: method lock, object lock, class lock?

Method lock (synchronized) :

Declare a synchronized method by adding the synchronized keyword to the method declaration.

Synchronized method controls access to class member variables;

Each synchronized method must obtain the lock of the class instance calling the method before it can be executed. Otherwise, the owning thread will be blocked. Once executed, the method will monopolize the lock until it is released when it returns from the method. This mechanism ensures that for each class instance at the same time, only one member function declared as synchronized is in the executable state at most, thus effectively avoiding the access conflict of class member variables.

Object lock (synchronized modifier or code block) :

When an object has a synchronized method or a synchronized block, the object lock must be acquired before the synchronized method of the object is called or the synchronized region of the object is entered. If the object lock on this object is already occupied by another caller, wait for the lock to be released. (Method locks are also object locks)

All Objects in Java contain a mutex, which is automatically acquired and released by the JVM. When a thread enters the synchronized method, it acquires the lock of the object. Of course, if another thread has acquired the lock of the object, the current thread will wait. The JVM automatically releases the object lock if the synchronized method returns normally or terminates with an exception. Another benefit of synchronized is that the lock can still be automatically released by the JVM when the method throws an exception.

Class locking (synchronized refers to static methods or code blocks):

Because a class has only one copy of its static methods and variables in memory, no matter how many times it is instantiated. So, once a static method is declared synchronized. All instantiated objects of this class share the same lock when calling this method, which we call the class lock.

Object locks are used to control synchronization between instance methods, and class locks are used to control synchronization between static methods (or static variable mutexes)

38 What happens if a thread within a synchronized block throws an exception?

The JVM automatically releases the object lock if the synchronized method returns normally or terminates with an exception

What’s the difference between concurrency and parallellism?

Explanation 1: Parallelism is when two or more events occur at the same time. Concurrency is when two or more events occur at the same time interval.

Explanation 2: Parallelism is multiple events on different entities, and concurrency is multiple events on the same entity.

Explanation 3: Multiple tasks “simultaneously” on one processor, multiple tasks on multiple processors at the same time. For example, hadoop distributed cluster, so the goal of concurrent programming is to make full use of each processor core to achieve the highest processing performance.

40 how to ensure that i++ results in multiple threads are correct?

Volatile only ensures that your data is visible and up-to-date, not atomicity.

AtomicInteger is used to ensure atomicity.

Synchronized can guarantee both the visibility of shared variables and the atomicity of in-lock operations.

What happens to a thread with a runtime exception?

If the exception is not caught, the thread stops executing.

Another important point is that if this thread holds a monitor for an object, the object monitor is immediately released.

42 How do I share data between two threads?

This is done by sharing objects between threads, and then evoking and waiting with wait/notify/notifyAll, await/signal/signalAll. For example, BlockingQueue is designed to share data between threads.

What is the role of the producer-consumer model?

The most important function of the producer-consumer model is to improve the operating efficiency of the whole system by balancing the production capacity of producers and the consumption capacity of consumers.

Decoupling, which is an incidental function of the producer-consumer model, means that there are fewer connections between producers and consumers, and the fewer connections, the more they can develop independently without being constrained by each other.

How do I wake up a blocked thread?

If the thread is blocked by calling wait(), sleep(), or join();

Suspend and resume:Java disallows suspend() because suspend() does not release any lock resources while suspending the thread. No other thread can access the lock it occupies. The suspended thread cannot resume until the corresponding thread executes resume(), and other threads blocked on the lock can resume execution. However, if the resume() operation occurs before suspend(), the thread remains suspended and holds the lock all the time, resulting in a deadlock. Moreover, the thread state of the suspended thread is still Runnable.

Wait and notify: Wait and notify must be used together with synchronized because a lock must be held before a call is called. Wait releases the lock immediately, while notify releases the lock only after the synchronized block is completed

Await is provided with the singal: Condition class, while the Condition object is obtained by new ReentLock().newcondition (), the same as wait and notify, because the wait method cannot be used with a Lock Lock

Park and Unpark: LockSupport is a very handy thread blocking tool that can block a thread anywhere. In contrast to thread.suspenf (), it makes up for the fact that the Thread can’t continue because resume() occurs before. Unlike Object.wait(), it does not need to acquire an Object lock first and does not throw an IException. Can wake up the specified thread. If the thread encounters AN IO block, there is nothing to be done, because IO is implemented by the operating system, and Java code has no direct access to the operating system.

45 What is the thread scheduling algorithm used in Java

Preemptive. After a thread runs out of CPU, the operating system calculates a total priority based on thread priority, thread hunger, etc., and allocates the next time slice to a particular thread.

46 Singleton thread-safety?

The threadbare issue is that singleton thread-safety means that instances of a class can only be created once in a multithreaded environment. There are several ways to write the singleton pattern, so LET me summarize:

(1) Writing method of Hunhan-style singleton pattern: thread safety

(2) Lazy singleton writing: not thread-safe

(3) Double lock singleton mode writing: thread safety

Which thread calls the constructor, static block of the thread class?

The thread constructor, the static block, is called by the thread of the new class, while the code inside the run method is called by the thread itself.

Which is a better choice, synchronization method or synchronization block?

A synchronized block is a better choice because it does not lock the entire object (you can also make it lock the entire object). Synchronized methods lock the entire object, even if there are multiple unrelated synchronized blocks in the class, which usually causes them to stop executing and wait to acquire the lock on the object.

Synchronized (this) and non-static synchronized methods (see below for static synchronized methods) only prevent multiple threads from simultaneously executing a synchronized snippet of the same object.

If you want to lock multiple object methods, you can either lock a fixed object or lock the Class object of that Class.

Synchronized locks objects in parentheses, not code. For non-static synchronized methods, the lock is the object itself, which is this.

49 How do I detect deadlocks? How do I prevent deadlocks?

Concept: refers to two or more processes in the implementation process, due to the competition for resources caused by a kind of mutual waiting phenomenon, if there is no external force, they will not be able to advance. The system is deadlocked.

Four necessary conditions for deadlocks:

Mutually exclusive: A process does not allow other processes to access the allocated resource. If other processes access the resource, they can only wait until the process that occupies the resource releases the resource

Request and hold conditions: After a process obtains a certain resource, it makes a request for another resource, but the resource may be occupied by another process. In this case, the request is blocked, but the obtained resource is held

Inalienable conditions: Resources acquired by a process cannot be taken away before they are used and can only be released after they are used

Loop waiting condition: after a process is deadlocked, several processes form a round-ending waiting resource relationship

Deadlock causes:

Deadlock due to competing resources: When the number of resources shared by multiple processes in the system is insufficient to meet the needs of all processes, the resource contention causes deadlock

A deadlock occurred due to improper process progression sequence

Check for deadlocks:

There are two containers, one for the locks that the thread is requesting and one for the locks that the thread already holds. The following tests are done before each lock

Check whether the currently requested lock is already held by another thread, and if so, find those threads

Iterate through the threads returned in the first step to see if the lock you hold is being requested by any of them. If the second step returns true, a deadlock has occurred

Deadlock relief and prevention:

Control not to make the four necessary conditions true.

50 What should I pay attention to when using HashMap in a multi-threaded environment?

Note the problem of dead loop. The HashMap put operation causes expansion, which can cause thread dead loop problems in multi-threaded concurrency.

HashMap is not thread-safe; Hashtable is thread safe, but inefficient because Hashtable is synchronized, and all threads compete for the same lock. ConcurrentHashMap is thread-safe and efficient because it contains an array of segments, stores data in segments, and assigns a lock to each segment.

Why HashMap threads are not safe

The same key in put overwrites the value of one thread.

Multiple threads are expanded simultaneously, causing data loss.

Next () infinite loop, resulting in CPU utilization close to 100%;

3. ConcurrentHashMap is the most efficient;

51 What is a daemon thread? What’s the use?

A daemon thread is a service thread, it’s a service thread, it’s a service thread, it’s a service thread, that’s what it does — there’s only one other thread, and that’s a user thread. So there are two kinds of threads in Java,

Daemon threads, such as garbage collection threads, are the most typical daemon threads.

2. User threads are custom threads in the application.

52 How to implement serial thread execution? A. In order to control the order in which threads execute, for example, ThreadA->ThreadB->ThreadC->ThreadA loop executes three threads, we need to determine the order in which we wake up and wait. This can be achieved by using obj.wait (), obj.notify (), and synchronized(Obj) simultaneously.

A thread holds the object lock of the previous thread class and its own lock. Because of this dependency, the thread execution needs to wait for the last object to release the lock, thus ensuring the order of execution of the class thread.

B. Normally, a thread releases the lock after acquiring the object lock and sleeps until another thread calls notify() to wake the thread. Notify (), on the other hand, is a wake up operation for a thread waiting for an object lock. It’s worth noting, however, that the notify() call does not release the object lock immediately, but rather at the end of the corresponding synchronized(){} block. After releasing the object lock, the JVM randomly assigns the object lock to one of the threads executing wait(), awakens the thread, and continues execution.

Can you kill a thread at runtime?

A. No, the thread has five states: New, runnable, Running, block, and dead.

B. A thread terminates its life cycle only when its run method or main method terminates, or when an exception is thrown.

54 on synchronized

Of all synchronized methods on an object, only a single thread can access those synchronized methods at any one time

If a method is synchronized, the synchronized keyword means that locking the current object (i.e., this) is equivalent to synchronized(this){}.

If a synchronized method is static, synchronized locks the corresponding class object of the current object (each class has only one corresponding class object, no matter how many objects are generated).

Step – by – step lock, deadlock mechanism and solution in program database

Basic principle: lock is represented by a status value, and lock occupation and release are identified by the status value.

Three types of distributed locks:

Zookeeper:

Distributed lock based on ZooKeeper instantaneous ordered node, its main logic is as follows. The general idea is: when each client locks a function, a unique instantaneous ordered node is generated in the directory of the specified node corresponding to this function on ZooKeeper. The way to determine whether to obtain the lock is very simple, just need to determine the smallest serial number in the ordered node. When the lock is released, the instantaneous node is simply removed. At the same time, it can avoid deadlock problems caused by locks that cannot be released due to service downtime

[Advantages] Lock security is high, ZK can be persistent, and can monitor the status of the client that obtains the lock in real time. Once the client goes down, the instant node disappears and ZK can release the lock first. This eliminates the need to add a timeout judgment to lock implementation with distributed caching.

Disadvantages: High performance overhead. Because it needs to dynamically generate and destroy instantaneous nodes to realize the locking function. Therefore, it is not suitable for direct use in high concurrency scenarios.

[Implementation] Distributed lock can be easily implemented by using the third-party library Curator of ZooKeeper.

[Application Scenario] This parameter is used in scenarios that have high reliability requirements and low concurrency. Such as timing full/incremental synchronization of core data.

The second memcached:

Memcached comes with the add function, which enables distributed locking. The difference between an Add and a set is that if multiple threads run sets concurrently, each set succeeds, but the value stored at the end depends on the thread of the last set. Add, on the other hand, adds the first value that arrives and returns true, while subsequent additions return false. This point makes it easy to implement distributed locking.

[Advantages] Concurrency is efficient

Disadvantages memcached uses an LRU substitution strategy, so if you run out of memory, you may lose lock information in the cache. Memcached cannot persist and information will be lost if you restart it.

Usage Scenario High concurrency scenario. 1) add a timeout to avoid deadlocks; 2) Provide enough memory space to support the lock service; 3) Stable cluster management.

The third Redis:

Redis distributed lock can be combined with zK distributed lock high security and high efficiency in memcached concurrent scenarios, its implementation is similar to memcached, using SETNx can be achieved. Note that redis here also needs to set timeout to avoid deadlocks. This can be implemented using the Jedis client.

Database deadlock mechanisms and solutions:

Deadlock: A deadlock is a phenomenon in which two or more transactions wait for each other during execution because they compete for locked resources.

Processing mechanism: The most useful and simple way to resolve deadlocks is to have no waits, convert any waits to rollback, and restart the transaction. However, concurrency performance may be affected.

—— Timeout rollback, innodb_lock_WAIT_time set timeout;

——wait-for-graph method: This is a more proactive deadlock detection method than timeout rollback. The InnoDB engine also uses this approach.

56 Spring singleton security issues (ThreadLocal)

1. ThreadLocal: Spring uses ThreadLocal to address thread safety issues; ThreadLocal provides a separate copy of variables for each thread, isolating conflicting data access from multiple threads. Since each thread has its own copy of the variable, there is no need to synchronize it. ThreadLocal provides thread-safe shared objects that can encapsulate unsafe variables in ThreadLocal when writing multithreaded code. To summarize, synchronization takes a time-for-space approach to the problem of multi-threaded resource sharing, while ThreadLocal takes a space-for-time approach. The former provides only one copy of a variable, which different threads queue to access, while the latter provides one copy of a variable for each thread, so it can be accessed simultaneously without affecting each other. In many cases, ThreadLocal is simpler and more convenient than directly using synchronized synchronization to address thread-safety issues, and the resulting program has higher concurrency.

2. Singleton: stateless Bean(stateless is an operation that cannot save data. Stateless beans are objects that have no instance variables, cannot hold data, are immutable classes, and are thread-safe. Suitable for immutable patterns, the technique is the singleton pattern, which can share instances and improve performance.

57 Thread Pool Principles

Usage scenario: Assume that the time required for a server to complete a task is: T1- time to create a thread, T2- time to execute the task in the thread, T3- time to destroy the thread. If T1+T3 is much larger than T2, thread pools can be used to improve server performance;

Composition:

ThreadPool manager: used to create and manage thread pools, including creating thread pools, destroying thread pools, adding new tasks;

PoolWorker: a thread in a thread pool that is in a waiting state when no task is available and can execute tasks in a loop.

Task interface: The interface that each Task must implement for the worker thread to schedule the execution of the Task. It mainly defines the entry of the Task, the finishing work after the Task is executed, and the execution status of the Task.

TaskQueue: Stores unprocessed tasks. Provide a buffer mechanism.

How it works: Thread pooling focuses on shortening or adjusting T1 and T3 times to improve server application performance. It schedules T1 and T3 at the start and end of the server program, or at some idle time, so that the server program does not have the overhead of T1 and T3 when processing client requests.

Workflow:

1. When the pool is first created, there are no threads in it (you can also set prestartAllCoreThreads to start the expected number of threads). The task queue is passed in as a parameter. However, even if there are tasks in the queue, the thread pool will not execute them immediately.

2. When the execute() method is called to add a task, the thread pool makes the following judgments:

If the number of running threads is less than corePoolSize, create a thread to run the task immediately.

If the number of running threads is greater than or equal to corePoolSize, the task is queued;

If the queue is full and the number of running threads is smaller than maximumPoolSize, create a non-core thread to run the task immediately.

If the queue is full and the number of running threads is greater than or equal to maximumPoolSize, the thread pool throws RejectExecutionException.

3. When a thread completes a task, it takes the next task from the queue and executes it.

4. When a thread has nothing to do for more than a certain keepAliveTime, the thread pool determines that if the number of threads currently running is greater than corePoolSize, the thread is stopped. So after all the tasks in the thread pool are complete, it will eventually shrink to the size of corePoolSize.

58 Java locks multiple objects

For example, when transferring money in the banking system, two synchronized accounts need to be locked. In this case, the sequential use of two synchronized may lead to deadlock

59 How do I start a Java thread

1. Inherit Thread;

2. Implement Runnable interface;

3. Directly in the function body:

Comparison:

1. Advantages of implementing Runnable interface:

1) It is suitable for multiple threads of the same program code to process the same resource

2) The restriction of single inheritance in Java can be avoided

3) Increase the robustness of the program, code can be shared by multiple threads, code and data independence.

2. Inheriting Thread class advantages:

1) Thread classes can be abstracted when using abstract factory pattern design.

2) Multithreading synchronization

3. Use advantages in function bodies

1) No need to inherit Thread or implement Runnable, narrow the scope.

60 Java lock in the way what, how to implement how to write?

1. There are two types of locks in Java: method or object locks (on non-static methods or blocks of code), and class locks (on static methods or classes).

2. Note that other threads can access unlocked methods and code; Synchronized modifies both static and instance methods, but the results run alternately, proving that class and object locks are two different locks that control different areas and do not interfere with each other.

61 How do I prevent data loss

1, the use of message queue, message persistence;

Add flag bit: 0 not processed, 1 in processing, 2 processed. Timed processing.

62, Why does ThreadLocal leak memory?

1. OOM implementation

The implementation of ThreadLocal looks like this: Each Thread maintains a ThreadLocalMap map whose key is the instance of ThreadLocal itself and whose value is the actual Object that needs to be stored. That is, ThreadLocal does not store values itself; it simply acts as a key for the thread to retrieve values from ThreadLocalMap. Note the dotted lines in the figure, which indicate that ThreadLocalMap uses a weak reference to ThreadLocal as the Key, and that the weakly referenced object is reclaimed during GC.

A ThreadLocalMap uses a weak reference to a ThreadLocal as its key. If a ThreadLocal has no external strong reference to it, then the ThreadLocal will be reclaimed during GC. There is no way to access the values of these null-key entries. If the current thread does not terminate, the values of these null-key entries will always have a strong reference chain: Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value can never be reclaimed, causing a memory leak.

Get (),set(), and remove() remove all null-key values from ThreadLocalMap. But these passive precautions are no guarantee against memory leaks:

(1) Static ThreadLocal extends the lifetime of ThreadLocal and may cause memory leaks.

(2) If ThreadLocal is allocated and the get(),set(), and remove() methods are not called, then the memory will leak because the memory will always be there.

63 improvements to ConcurrentHashmap in JDK8

Java 7 introduces the Segment structure to achieve parallel access, and implements segmental locking. Theoretically, the maximum concurrency is equal to the number of segments.

To further improve concurrency, Java 8 eliminates the piecewise locking scheme and instead uses a large array. In order to improve addressing performance under hash collisions, Java 8 converts linked lists (addressing time complexity O(N)) to red-black trees (addressing time complexity O(long(N)) when the list length exceeds a certain threshold (8).

What classes are available under the 64 Concurrent package?

ConcurrentHashMap, Future, FutureTask, AtomicInteger…

65 Thread A, B, C, and D run the task. How can I ensure that thread A, B, and C finish the task before thread D?

1, CountDownLatch class

A synchronization helper class that is used when a condition occurs before subsequent processes can be executed. Given the count to initialize CountDownLatch, the countDown() method is called and the await method blocks until the count reaches zero.

Important methods are countdown() and await();

2. Join method

Add thread B to the tail of thread A and wait until thread A finishes executing.

3. Notify and wait methods, wake up and wait methods in Java, the key is synchronized code block, parameter thread should be the same, also commonly used as Object parameter.

How to optimize the performance of high concurrency system? How to prevent oversold inventory?

1. High concurrency system performance optimization: optimize programs, service configuration, and system configuration

Try to use cache, including user cache, information cache, etc., spend more memory to do cache, can greatly reduce the interaction with the database, improve performance.

Use tools such as Jprofiler to identify performance bottlenecks and reduce additional overhead.

Optimize database query statements to reduce directly generated statements using tools such as Hibernate (only long queries are optimized).

Optimize database structure, do more index, improve query efficiency.

Statistical functions should be cached as far as possible, or related reports should be collected on a daily basis or at regular intervals to avoid statistical functions when needed.

Use static pages wherever possible and minimize container parsing (try to generate static HTML to display dynamic content).

After solving the above problems, use a server cluster to solve the bottleneck problem of a single server.

2. Prevent oversold inventory:

Pessimistic locking: Locks are placed during inventory update and do not allow other threads to modify.

Database lock: select XXX for update;

Distributed lock;

Optimistic locks: Use updates with version numbers. Each thread can modify concurrently, but only one thread will succeed and the others will return a failure.

Redis Watch: Monitors key-value pairs. If a change is detected in the monitored pair when the transaction submits to exec, the transaction will be cancelled.

Message queues: Serialize operations to modify inventory through FIFO queues.

Conclusion:

In general, you can’t put pressure on the database, so using “Select XXX for Update” is not feasible in high concurrency scenarios. FIFO synchronous queue can be combined with inventory to limit queue length, but in the scenario of large inventory, it is not suitable. So, relatively speaking, I prefer the optimistic/cache/distributed lock approach.

Willing to output dry Java technology public number: Wolf king programming. The public number has a large number of technical articles, massive video resources, beautiful brain map, might as well pay attention to it! Get lots of learning resources and free books!

Forwarding moments is the biggest support for me!

\

Click “like and watching” if you feel something! Thank you for your support!