1. What is the difference between parallelism and concurrency?

  • 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.
  • Parallelism is multiple events on different entities, and concurrency is multiple events on the same entity.
  • “Simultaneous” processing of multiple tasks on one processor, multiple tasks on multiple processors. Such as Hadoop distributed cluster.

So the goal of concurrent programming is to make full use of every core of the processor to achieve maximum processing performance.

2. What is the difference between threads and processes?

In short, a process is the basic unit of program execution and resource allocation. A program has at least one process and a process has at least one thread. A process has a separate memory unit during execution, while multiple threads share memory resources, reducing the number of switches and making it more efficient. A thread is an entity of a process. It is the basic unit of CPU scheduling and dispatching. It is a basic unit smaller than a program that can run independently. Multiple threads in the same process can execute concurrently.

3. What is a daemon thread?

A daemon thread, or daemon thread, is a service thread, specifically a service thread to another thread.

4. What are the ways to create a thread?

Create Thread class by inheriting Thread class

  • Subclass Thread and override the run method of the class. The body of the run method represents the task to be completed by the Thread. Therefore, the run() method is called the body of the execution.
  • Creating an instance of the Thread subclass creates a Thread object.
  • Call the start() method of the thread object to start the thread.

②. Create thread classes through the Runnable interface

  • Define the implementation class of the Runnable interface and override the run() method of that interface, whose method body is also the thread execution body of that thread.
  • Create an instance of the Runnable implementation class and use this instance as the target of a Thread to create a Thread object, which is the actual Thread object.
  • Call the start() method of the thread object to start the thread.

③ Create threads with Callable and Future

  • Create an implementation class for the Callable interface that implements the Call () method, which acts as the thread body and has a return value.
  • Create an instance of the Callable implementation class that wraps the Callable object with a FutureTask class that wraps the return value of the Callable object’s call() method.
  • Create and start a new Thread using the FutureTask object as the target of the Thread object.
  • Call the Get () method of the FutureTask object to get the return value after the child thread completes execution.

5. What is the difference between runnable and callable?

A bit of a deep question, but also see a Java programmer to learn the breadth of knowledge.

  • 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.

6. What are the states of threads?

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

  • Create state. When a thread object is generated, the object’s start method is not called, which is the thread being created.
  • Ready state. 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.
  • Running status. 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.
  • Blocked status. 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.
  • State of 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

7. What’s the difference between sleep() and wait()?

Sleep () : The method is a static method of Thread class, which makes the calling Thread go to sleep 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 CPU execution time. 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 () : 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 so that other threads can access the wait. NotifyAll and notify methods are used to wake up the waiting thread

What is the difference between notify() and notifyAll()?

  • If a thread calls an object’s wait() method, it is in that object’s wait pool, and the threads in the wait pool do not compete for the lock on that object.
  • When a thread calls notifyAll() or notify() of an object (only one wait 88 thread is awakened at random), the awakened thread enters the lock pool of the object and the threads compete for the lock. That is, after notify is called, only one thread enters the lock pool from the wait pool, and notifyAll moves all threads in the wait pool to the lock pool, waiting for lock contention.
  • A thread with a higher priority has a higher probability of competing for an object lock. If a thread does not compete for the object lock, it will remain in the lock pool and only return to the wait pool if the thread calls wait() again. The thread that contended for the object lock continues to execute until the synchronized block is finished, which releases the object lock, at which point the pool of threads continues to contend for the object lock.

9. What is the difference between run() and start() for a thread?

Each Thread completes its operations through a method run() corresponding to a particular Thread object, called the Thread body. Start a Thread by calling the start() method of the Thread class.

The start() method is used to start a thread, truly implementing multithreading. Instead of waiting for the body of the run method to finish executing, you can continue with the following code. The thread is in a ready state and is not running. The Thread class then calls the method run() to complete its running state. The method run() is called the Thread body, which contains the contents of the Thread to be executed. The run method ends and the Thread terminates. The CPU then schedules other threads.

The run() method is local to the thread, just a function in the thread, not multithreaded. If you call run() directly, it is just like calling a normal function. If you call run() directly, you have to wait for the run() method to complete before you can execute the following code. Therefore, 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.

10. What are the ways to create a thread pool?

1. NewFixedThreadPool (int nThreads)

Create a thread pool of fixed length, each time a task is submitted, one thread is created until the maximum number of threads in the pool is reached, at which point the thread size does not change, and when a thread terminates with an unexpected error, a new thread is added to the pool.

(2). NewCachedThreadPool ()

Create a cacheable thread pool that automatically recycles idle threads if the size of the thread pool exceeds processing requirements, and automatically adds new threads when demand increases. There is no limit to the size of the thread pool.

(3). NewSingleThreadExecutor ()

This is a single-threaded Executor that creates a single worker thread to execute a task, and if this thread terminates abnormally, a new one is created to replace it; It features the ability to ensure that tasks are executed sequentially according to the order in the queue.

(4). NewScheduledThreadPool (int corePoolSize)

A fixed length thread pool is created and tasks are executed in a deferred or timed manner, similar to a Timer.

What are the states of the thread pool?

Thread pools are in five states: Running, ShutDown, Stop, Tidying, and Terminated.

Thread pool each state switch block diagram:

12. What is the difference between submit() and execute() methods in the thread pool?

  • The received parameters are different
  • Submit returns a value, but execute does not
  • Submit facilitates Exception handling

13. How to ensure the safety of multithreading in Java procedures?

Thread safety is embodied in three aspects:

  • Atomicity: provides mutually exclusive access and only one thread can operate on data at a time (atomic,synchronized);
  • Visibility: Changes made by one thread to main memory can be seen by other threads in a timely manner (synchronized,volatile);
  • Orderliness: One thread observes the order in which instructions are executed in another thread, and the observation is often disorderly due to instruction reordering (happens-before principle).

14. What is the upgrade principle of multi-threaded lock?

In Java, there are four lock states, ranked from lowest to highest: stateless, biased, lightweight, and heavyweight, which escalate as the race progresses. Locks can be upgraded but not degraded.

Graphical process of lock upgrade:

15. What is a deadlock?

A deadlock is a phenomenon in which two or more processes are blocked during execution, either by competing for resources or by communicating with each other, and cannot proceed without external action. The system is said to be in a deadlock state or a deadlock occurs in the system. These processes that are always waiting for each other are called deadlocked processes. An error at the operating system level, it is short for process deadlock. It was first proposed by Dijkstra in 1965 while working on banker algorithms. It is one of the most difficult problems to deal with in computer operating systems and in the whole field of concurrent programming.

16. How to prevent deadlocks?

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 has obtained a certain resource, it makes a request for another resource, but the resource may be occupied by another process. 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

These four conditions are necessary for deadlocks, and they must be true whenever a deadlock occurs on the system, and no deadlock occurs unless one of these conditions is met.

Understanding the causes of deadlocks, especially the four necessary conditions for deadlocks, can best avoid, prevent, and remove deadlocks.

Therefore, in system design, process scheduling and other aspects to pay attention to how not to let the four necessary conditions set up, how to determine the reasonable allocation of resources algorithm, to avoid process permanent occupation of system resources.

Also, prevent processes from taking up resources while they are in a wait state. Therefore, the allocation of resources should be given reasonable planning.

17. What is ThreadLocal? What are the usage scenarios?

Thread-local variables are variables that are limited within a thread and are owned by the thread itself and are not shared between multiple threads. Java provides a ThreadLocal class to support thread-local variables as a way to achieve thread-safety. However, be careful when using thread-local variables in a managed environment, such as a Web server, where the life of a worker thread is longer than the life of any application variable. Java applications run the risk of memory leaks if any thread-local variables are not released after work is done.

18. Talk about the underlying implementation of synchronized.

Synchronized ensures that only one method or block of code can enter a critical section at any one time at runtime, and it also ensures memory visibility of shared variables.

Every object in Java can be used as a lock, which is the basis for synchronized:

  • For normal synchronization methods, the lock is the current instance object
  • Statically synchronized methods where the lock is the class object of the current class
  • Synchronized method block, lock is the object inside parentheses

19. What is the difference between synchronized and volatile?

  • Volatile essentially tells the JVM that the value of the current variable in the register (working memory) is indeterminate and needs to be read from main memory;
  • Synchronized locks the current variable so that only the current thread can access it and other threads are blocked.
  • Volatile can only be used at the variable level; Synchronized can be used at the variable, method, and class levels.
  • Volatile only enables change visibility of variables, not atomicity. Synchronized can guarantee the change visibility and atomicity of variables.
  • Volatile does not block threads; Synchronized can cause threads to block.
  • Volatile variables are not optimized by the compiler; Variables of the synchronized tag can be optimized by the compiler.

20. What’s the difference between synchronized and Lock?

  • Synchronized is a built-in Java keyword, and Lock is a Java class at the JVM level.
  • Synchronized cannot determine whether the Lock is obtained. Lock can determine whether the Lock is obtained.
  • Synchronized automatically releases the lock (a thread releases the lock after executing the synchronization code; The Lock must be released manually in finally (unlock()). Otherwise, the thread is likely to deadlock.
  • Two threads 1 and 2 that use the synchronized keyword, if the current thread 1 acquires the lock, thread 2 waits. If thread 1 is blocked, thread 2 will wait forever, while Lock does not necessarily wait. If an attempt to acquire the Lock fails, the thread can terminate without waiting forever.
  • Synchronized locks are reentrant, uninterruptible, and non-fair, whereas Lock locks are reentrant, judgeable, and fair (both).
  • Lock locks are suitable for synchronization problems with a lot of synchronized code, and synchronized locks are suitable for synchronization problems with a small amount of synchronized code.

21. What is 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 provides flexibility for multiple notifications

Unsafe Lock (ReentrantLock) refers to the Unsafe park method, whereas synchronized refers to the Mark Word object header.

22. How does atomic work?

Atomic package basic feature is the class in a multithreaded environment, when there are multiple threads at the same time for a single (including basic types and reference types) variables, exclusive, when multiple threads on the value of the variable is updated at the same time, there is only one thread can be successful, but not the thread can to spin locks to success, keep trying, Wait until the execution succeeds.

The core methods in the Atomic family classes all call several native methods in the Unsafe class. The first thing you need to know is the Unsafe class, whose full name is: Sun.misc.Unsafe, the Unsafe class contains numerous operations on C code, including calls to direct memory allocation and atomic operations. Addressing Unsafe, sun.misc. For example, when allocating memory using unsafe, specifying areas may result in Pointers to other processes, as in C++.

The last

Thank you for reading here, the article is inadequate, welcome to point out; If you think it’s good, give me a thumbs up.

Also welcome to pay attention to my public number: programmer Maidong, Maidong will share Java related technical articles or industry information every day, welcome to pay attention to and forward the article!