Writing in the front

Arrange some interview questions with Internet companies, these interview questions are often asked, also as a Java engineer need to master the knowledge, after all, the combination of theory and practice, is king, fragmentation, eat some knowledge every day, happy every day, if you have any help to you, remember the point attention and point oh.

Related articles

MyBatis (MyBatis) (ZooKeeper) (Dubbo) (Elasticsearch) (Redis) (MySQL) (Dubbo) Java concurrent programming interview questions (1)

Three elements of concurrent programming?

  • Atomicity Atomicity refers to the fact that one or more operations are either all performed without interruption by other operations or none performed at all.
  • Visibility Visibility means that when multiple threads operate on a shared variable, when one thread makes changes to the variable, the other threads can see the changes immediately.
  • Orderliness: the order in which a program is executed is the order in which the code is executed.

What are the ways to achieve visibility?

Synchronized or Lock: ensure that only one thread at a time obtains the Lock execution code, and refresh the latest value to the main memory before releasing the Lock to achieve visibility.

The value of multithreading?

  • Multi-threading, can really play the advantages of multi-core CPU, to make full use of the PURPOSE of THE CPU, the use of multi-threading way to complete several things at the same time without interfering with each other.
  • From the point of view of program running efficiency, single-core CPU will not give full play to the advantages of multi-threading, but will cause the thread context switch to run multi-threading on single-core CPU, and reduce the overall efficiency of the program. But with a single-core CPU we still have to apply multiple threads, just to prevent blocking. Imagine if a single-core CPU uses a single thread, and if that thread blocks, say, reading data remotely, and the peer does not return and does not set a timeout, your entire program will stop running before the data is returned. Multithreading prevents this problem. Multiple threads are running at the same time. Even if one thread’s code execution blocks data reading, it does not affect the execution of other tasks.
  • Modeling is another, less obvious advantage. Let’s say you have A big task A, single-threaded programming, and it’s A lot to think about, and it’s A lot of trouble to model the entire program. But if this big task A is broken down into several small tasks, task B, task C, task D, respectively establish the program model, and run these tasks through multithreading, it will be much simpler.

What are the ways to create a thread?

  • Create a Thread class by inheriting the Thread class
  • Create thread classes through the Runnable interface
  • Create threads through Callable and Future
  • Created from a thread pool

How do you compare the three ways to create threads?

  • Using Runnable, Callable interface to create multithreading

The advantage is that thread classes simply implement the Runnable or Callable interfaces and can inherit from other classes. In this way, multiple threads can share the same target object, so it is very suitable for multiple same threads to deal with the same resource, so that the CPU, code and data can be separated, forming a clear model, better reflects the idea of object-oriented. The downside: the programming is a bit complicated, and if you want to access the currentThread, you must use the thread.currentthread () method.

  • Create multiple threads by inheriting the Thread class

The advantage is that it is easy to write. If you need to access the currentThread, you can use this to get the currentThread without using thread.currentthread (). The disadvantage is that Thread classes already inherit from Thread, so they cannot inherit from other parent classes.

  • Difference between Runnable and Callable

    • The Callable specified (overridden) method is call() and the Runnable specified (overridden) method is run().
    • Callable tasks return values after execution, while Runnable tasks do not.
    • The Call method can throw an exception, but the run method cannot.
    • Running the Callable task retrieves a Future object that represents the result of the asynchronous calculation. It provides a way to check that a calculation is complete, wait for it to complete, and retrieve the results of the calculation. By using the Future object, you can know the execution status of the task, cancel the execution of the task, and obtain the execution result.

Java threads have five basic states

  • New State (New)When a thread object pair is created, it enters the new state.Thread t = new MyThread();
  • Runnable stateWhen the start() method of a thread object is called (t.start();), the thread enters the ready state. When a thread is in the ready state, it is ready to be executed by the CPU, not when t.start() is executed.
  • Running: When the CPU starts scheduling a thread in the ready state, the thread can actually execute, that is, enter the Running state. Note: the thread state is the only entry into the running state, that is, to enter the running state execution, the thread must first be in the ready state;
  • Blocked: A running thread temporarily relinquish access to the CPU and stops executing for some reason. At this point, the thread enters the Blocked state and is not called again by the CPU until it enters the ready state.

According to different causes of blocking, blocking states can be divided into three types:

  • Wait to block: a running thread executes wait() to make it wait to block.
  • Synchronized blocking: a thread that fails to acquire a synchronized lock (because the lock is occupied by another thread) enters the synchronized blocking state.
  • Other blocking: A thread is blocked by calling its sleep() or join() or by making an I/O request. When the sleep() state times out, when the join() wait thread terminates or times out, or when I/O processing is complete, the thread goes back to the ready state.
  • Dead: a thread terminates its life cycle when it finishes executing or exits the run() method because of an exception.

What is a thread pool? What are the ways to create it?

A thread pool is a pool of threads that are created in advance. If there is a task that needs to be processed, the threads in the pool will handle the task. After processing, the thread will not be destroyed, but wait for the next task. Since creating and destroying threads consumes system resources, consider using thread pools when you want to create and destroy threads frequently to improve system performance. Java provides a Java. Util. Concurrent. The realization of the Executor interface is used to create a thread pool.

Four types of thread pool creation

  • NewCachedThreadPool Creates a cacheable thread pool
  • NewFixedThreadPool Creates a fixed-length thread pool that controls the maximum number of concurrent threads.
  • 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 a single worker thread to perform tasks.

What are the advantages of thread pools?

  • Reuse existing threads to reduce the overhead of object creation and destruction.
  • It can effectively control the maximum number of concurrent threads, improve system resource usage, and avoid excessive resource contention and congestion.
  • Provides scheduled execution, periodic execution, single thread, concurrency control and other functions.

What are the common concurrency utility classes?

  • CountDownLatch
  • CyclicBarrier
  • Semaphore
  • Exchanger

CyclicBarrier and CountDownLatch

  • CountDownLatch is simply a thread waiting until all the other threads it is waiting on have completed and are notified by calling countDown().
  • CyclicBarrier is when all threads wait until all threads are ready to enter the await() method, and all threads start executing at the same time!
  • CountDownLatch’s counter can only be used once. CyclicBarrier counters can be reset with the reset() method. So CyclicBarrier can handle more complex business scenarios, such as resetting counters and having threads execute again if a calculation goes wrong.
  • CyclicBarrier also provides other useful methods, such as the getNumberWaiting method that tells you how many threads a CyclicBarrier is blocking. The isBroken method is used to know if a blocking thread is interrupted. Returns true if interrupted, false otherwise.

The role of synchronized?

In Java, the synchronized keyword is used to control thread synchronization, which prevents synchronized code from being executed by multiple threads in a multithreaded environment. Synchronized can be added to either a piece of code or a method.

The role of the volatile keyword

For visibility, Java provides the volatile keyword to ensure visibility. When a shared variable is volatile, it guarantees that the value is immediately updated to main memory, and that it will read the new value in memory when another thread needs to read it. From the point of the practice, is an important role of volatile and CAS, guarantees the atomicity and detail can see Java. Util. Concurrent. The atomic classes under the package, such as AtomicInteger.

What is the CAS

CAS stands for compare and swap, as we call it. Cas is a lock-based operation, and it is optimistic locking. In Java, there are optimistic locks and pessimistic locks. A sad lock is a resource that is locked until the next thread can access it after the previous thread that acquired the lock releases the lock. Optimistic locking, which takes a broad approach and processes resources in some way without locking, such as fetching data by adding version to records, has a significant performance improvement over pessimistic locking.

The CAS operation contains three operands — the memory location (V), the expected old value (A), and the new value (B). If the value in the memory address is the same as the value of A, then the value in memory is updated to B. CAS fetches data through an infinite loop. If thread A gets the address in the first loop and the value in the address is changed by thread B, then thread A needs to spin until the next loop is executed. Java. Util. Concurrent. Atomic package under most of the class is implemented using CAS operation (AtomicInteger AtomicBoolean, AtomicLong).

The problem of the CAS

  • CAS is prone to ABA problems. A thread A changes its value to B and then to A, and CAS thinks it has not changed, but in fact it has changed. The solution to this problem can be identified by the version number, and version increases by 1 for each operation. In java5, AtomicStampedReference is already provided to solve the problem.
  • No guarantee of atomicity the CAS mechanism guarantees the atomicity of a variable but not the entire code block. For example, synchronized is used to ensure that all three variables are updated atomically.
  • As mentioned earlier, the CAS process is a loop. If the thread does not obtain the status, the CPU resources will remain occupied.

What is Future?

In concurrent programming, we often use the non-blocking model. In the previous three implementations of multithreading, there was no guarantee of obtaining the results of the previous execution, regardless of whether the Thread class was inherited or the runnable interface was implemented. By implementing the Callback interface and using the Future, you can receive multithreaded execution results. A Future represents the result of an asynchronous task that may not have completed, to which a Callback can be added to act upon the success or failure of the task.

What is the AQS

AQS is short for AbustactQueuedSynchronizer, it is a Java improve the bottom of the synchronous tools, expressed in a variable of type int synchronization state, and provides a series of CAS operations to management the sync. AQS is a framework for building locks and synchronizers. It is easy and efficient to build a wide range of synchronizers, such as ReentrantLock, Semaphore, and others such as ReentrantReadWriteLock. SynchronousQueue, FutureTask, and so on are all based on AQS.

AQS supports two synchronization modes

  • exclusive
  • Shared

This allows users to implement different types of synchronization components, such as exclusive ReentrantLock, shared Semaphore, CountDownLatch, and combined such as ReentrantReadWriteLock. In short, AQS provide the underlying support for use, and the user is free to assemble the implementation.

What is the ReadWriteLock

To be clear, it’s not that ReentrantLock is bad, it’s just that ReentrantLock is sometimes limited. If you use ReentrantLock, it may be to prevent data inconsistency caused by thread A writing data and thread B reading data. However, if thread C is reading data and thread D is also reading data, the read data will not change the data. There is no need to lock the data, but the lock is still locked. Reduces the performance of the program. Because of this, the read-write lock ReadWriteLock was born. ReadWriteLock is a read/write lock interface. ReentrantReadWriteLock is a concrete implementation of the ReadWriteLock interface. It enables read and write separation. Read and write, write and read, and write and write are mutually exclusive, improving read and write performance.

What is FutureTask

This was actually mentioned earlier, FutureTask represents a task for asynchronous computation. FutureTask can pass in a concrete implementation class of Callable, which can wait for the result of the asynchronous operation, determine whether the task has been completed, and cancel the task. Of course, since FutureTask is also an implementation class of the Runnable interface, it can also be put into a thread pool.

The difference between synchronized and ReentrantLock

Synchronized is a keyword like if, else, for, and while. ReentrantLock is a class. This is the essential difference between synchronized and while. Since ReentrantLock is a class, it provides more flexible features than synchronized. It can be inherited, can have methods, and can have a variety of class variables. ReentrantLock has more extensibility than synchronized in several aspects:

  • ReentrantLock prevents deadlocks by setting the wait time for acquiring locks
  • ReentrantLock can obtain information about various locks
  • ReentrantLock is a flexible way to implement multiple notifications. In addition, the locking mechanism is different. The underlying ReentrantLock is the Unsafe park method, while synchronized is the mark Word object header. I’m not sure.

What are optimistic locks and pessimistic locks

Optimistic locking: just as its name, for concurrent operation thread safety problem between state, optimistic optimistic locking that competition does not always happen, so it doesn’t need to hold the lock, will compare – to replace the two actions as an atomic operation to try to modify variables in memory, if failure, said conflict, then there should be corresponding retry logic.

Pessimistic lock: As its name suggests, pessimistic locks take a pessimistic view of thread-safety issues arising from concurrent operations. Pessimistic locks assume that competition always occurs and therefore hold an exclusive lock every time a resource is operated on, just like synchronized.

How does thread B know that thread A changed A variable

  • Volatile modifies variables
  • Synchronized modifies the method of modifying variables
  • wait/notify
  • While polling

Synchronized, volatile, CAS comparison

  • Synchronized is a pessimistic lock, which is preemptive and causes other threads to block.
  • Volatile provides multithreaded shared variable visibility and disallows instruction reordering optimization.
  • CAS is optimistic lock based on collision detection (non-blocking)

What is the difference between the sleep method and the wait method?

Sleep and wait can both be used to give up the CPU for a certain amount of time. The difference is that if a thread holds the monitor for an object, sleep does not give up the monitor for that object, while wait does

What is a ThreadLocal? What’s the use?

ThreadLocal is a local thread copy variable utility class. It is mainly used to make a mapping between the private thread and the copy object stored by the thread. The variables between each thread do not interfere with each other. In the high concurrency scenario, stateless call can be realized, especially suitable for the scenario where each thread relies on impassable variable value to complete the operation. Simple said ThreadLocal is a kind of to the practice of trading space for time, in each Thread maintains a method to implement ThreadLocal. With open address ThreadLocalMap, isolating data, data is not Shared, nature is no Thread safety issues.

Why are wait() and notify()/notifyAll() called in synchronous blocks

This is mandatory by the JDK; both wait() and notify()/notifyAll() must acquire the lock on the object before being called

What are the methods of multithreaded synchronization?

Synchronized keyword, Lock Lock implementation, distributed Lock and so on.

Scheduling policy for threads

The thread scheduler selects the thread with the highest priority to run, but terminates the thread if:

  • The yield method is invoked in the thread body to yield CPU usage
  • The sleep method is called in the thread body to put the thread to sleep
  • The thread is blocked due to AN I/O operation
  • Another thread of higher priority appears
  • On a system that supports timeslices, the thread ran out of timeslices

What is the concurrency of ConcurrentHashMap

ConcurrentHashMap concurrency is the size of the segment. The default value is 16, which means that a maximum of 16 threads can operate the ConcurrentHashMap simultaneously. This is also the biggest advantage of ConcurrentHashMap over Hashtable. In any case, can two threads fetch data from Hashtable at the same time?

How do I find which thread is using the longest CPU in Linux

  • Access to the pid of the project, the JPS or ps – ef | grep Java, the front has spoken
  • Top-h-p PID, the order cannot be changed

Java deadlocks and how to avoid them?

A deadlock in Java is a programming condition in which two or more threads are permanently blocked, and a Java deadlock occurs in which at least two threads and two or more resources occur. The root cause of deadlock in Java is that a cross closed loop application occurs during lock application.

Cause of deadlock

  • Multiple threads involve multiple locks, and the locks are crossed, so a lock-dependent closed loop can result. For example, A thread applies for lock B when it has acquired lock A and has not released it. At this point, another thread has acquired lock B and needs to acquire lock A before releasing lock B. Therefore, A closed loop occurs and A deadlock loop occurs.
  • The default lock request operation is blocked. Therefore, to avoid deadlocks, every time multiple object locks are crossed, all methods in these classes should be carefully examined for the possibility of lock-dependent loops. In general, try to avoid calling delayed methods and synchronized methods of other objects in a synchronized method.

How do I wake up a blocked thread

If a thread is blocking because it called wait(), sleep(), or join(), you can interrupt the thread and wake it up by throwing InterruptedException. 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.

How can immutable objects help multithreading

As mentioned earlier, immutable objects guarantee the memory visibility of objects, and reading immutable objects does not require additional synchronization, which improves code execution efficiency.

What is multithreaded context switching

Context switching in multithreading is the process of switching CPU control from one thread that is already running to another thread that is ready and waiting for CPU execution.

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

Here’s the distinction:

  • If you use an unbounded queue called LinkedBlockingQueue, you can 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
  • If you are using a bounded queue such as ArrayBlockingQueue, the task is first added to the ArrayBlockingQueue. When the ArrayBlockingQueue is full, the number of threads is increased based on maximumPoolSize. If the number of threads increases and ArrayBlockingQueue continues to fill up, then the full task will be processed using the RejectedExecutionHandler policy, which is AbortPolicy by default

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.

What are Thread schedulers and TimeSlicing?

The Thread scheduler is an operating system service that allocates CPU time to Runnable threads. Once we create a thread and start it, its execution depends on the implementation of the thread scheduler. Time fragmentation is the process of allocating available CPU time to available Runnable threads. CPU time can be allocated based on thread priority or the amount of time a thread waits. Thread scheduling is not controlled by the Java VIRTUAL machine, so it is better for the application to control it (that is, don’t make your application dependent on thread primacy).

What is spin

A lot of synchronized code is just some very simple code, the execution time is very fast, in this case, waiting for threads to lock may not be a worthwhile operation, because thread blocking involves user state and kernel state switch issues. Since synchronized code executes so fast, it’s a good idea not to block a thread waiting for a lock, but to do a busy loop at synchronized’s boundary, which is known as spin. It may be a better strategy to block after doing several busy loops and not getting the lock.

What is the Lockinterface in JavaConcurrencyAPI? What are the advantages over synchronization?

The Lock interface provides a more extensible locking operation than synchronized methods and synchronized blocks. They allow more flexible constructs, can have completely different properties, and can support conditional objects of multiple related classes. Its advantages include:

  • Can make locks fairer
  • Threads can be made to respond to interrupts while waiting for locks
  • You can have a thread attempt to acquire the lock and either return immediately or wait a certain amount of time if the lock cannot be acquired
  • Locks can be acquired and released in different order in different scopes

Thread safety in singleton mode

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:

  • The hunchman singleton pattern is written as thread-safe
  • Lazy singleton: not thread-safe
  • Double lock singleton is written as thread safe

What does Semaphore do

A Semaphore is a Semaphore that limits the number of concurrent requests for a block of code. Semaphore has a constructor that passes in an integer of type n, indicating that a piece of code can be accessed by at most N threads. If the number of threads exceeds n, wait until one thread finishes executing the block before the next thread enters. If the Semaphore constructor passes an int n=1, it becomes synchronized.

Executors?

Executors provide tools and methods for Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, and Callable classes. Executors can be used to easily create thread pools

The constructor of the thread class, the static block, is called by which thread

This is a very tricky and tricky question. Remember: the thread constructor, the static block, is called by the thread in which the new thread belongs, whereas the code in the run method is called by the thread itself. For example, if Thread1 is new in Thread2 and Thread2 is new in main, then: Thread2 uses the run() method called by the main thread and the static block called by Thread2. Thread1’s run() method is called by Thread1 itself

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

Block synchronization, which means that code outside the block is executed asynchronously, which is more efficient than synchronizing the entire method. As a rule of thumb, the smaller the scope of synchronization, the better.

What exceptions can be caused by too many Java threads?

  • Thread lifecycle overhead is very high
  • If the number of threads available to run exceeds the number of available processors, threads will become idle. A large number of idle threads can take up a lot of memory, stress the garbage collector, and incur other performance costs as a large number of threads compete for CPU resources.
  • Reducing stability The JVM has a limit on the number of threads that can be created. This limit varies from platform to platform and is subject to several factors, including the JVM’s startup parameters, the size of the request stack in the Thread constructor, and Thread restrictions imposed by the underlying operating system. If these restrictions are broken, an OutOfMemoryError may be thrown.