亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Home Java JavaInterview questions Java concurrency basics common interview questions (summary)

Java concurrency basics common interview questions (summary)

Nov 23, 2019 pm 04:37 PM
java spring

This article summarizes common Java concurrency basic interview questions for everyone. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

Java concurrency basics common interview questions (summary)

1. What are threads and processes?

1.1. What What is a process?

A process is an execution process of a program and is the basic unit for system running programs, so the process is dynamic. Running a program on the system is the process from creation, operation to death of a process.

In Java, when we start the main function, we actually start a JVM process, and the thread where the main function is located is a thread in this process, also called the main thread.

As shown in the figure below, by viewing the Task Manager in windows, we can clearly see the process currently running in the window (the running of the .exe file).

Java concurrency basics common interview questions (summary)

1.2. What is a thread?

Threads are similar to processes, but threads are different than processes Smaller units of execution. A process can generate multiple threads during its execution. Different from a process, multiple threads of the same type share the heap and method area resources of the process, but each thread has its own program counter, Virtual machine stack and local method stack, so when the system generates a thread or switches between threads, the burden is much smaller than that of the process. Because of this, threads also It is called a lightweight process.

Java programs are inherently multi-threaded programs. We can use JMX to see what threads an ordinary Java program has. The code is as follows.

public?class?MultiThread?{
????public?static?void?main(String[]?args)?{
????????//?獲取?Java?線程管理?MXBean
????ThreadMXBean?threadMXBean?=?ManagementFactory.getThreadMXBean();
????????//?不需要獲取同步的?monitor?和?synchronizer?信息,僅獲取線程和線程堆棧信息
????????ThreadInfo[]?threadInfos?=?threadMXBean.dumpAllThreads(false,?false);
????????//?遍歷線程信息,僅打印線程?ID?和線程名稱信息
????????for?(ThreadInfo?threadInfo?:?threadInfos)?{
????????????System.out.println("["?+?threadInfo.getThreadId()?+?"]?"?+?threadInfo.getThreadName());
????????}
????}
}

The output of the above program is as follows (the output content may be different, don’t worry too much about the role of each thread below, just know that the main thread executes the main method):

[5]?Attach?Listener?//添加事件
[4]?Signal?Dispatcher?//?分發(fā)處理給?JVM?信號的線程
[3]?Finalizer?//調(diào)用對象?finalize?方法的線程
[2]?Reference?Handler?//清除?reference?線程
[1]?main?//main?線程,程序入口

From the above output The content can be seen: The running of a Java program is the main thread and multiple other threads running simultaneously.

2. Please briefly describe the relationship, differences, advantages and disadvantages between threads and processes?

The relationship between processes and threads from the perspective of JVM

2.1. Illustration of the relationship between processes and threads

The following figure is the Java memory area. Through the following figure, we can talk about the relationship between threads and processes from the perspective of JVM. If you don’t know much about the Java memory area (runtime data area), you can read this article: "Probably the clearest article that explains the Java memory area"


Java concurrency basics common interview questions (summary)

As can be seen from the above figure: there can be multiple threads in a process, and multiple threads share the heap# of the process ## and Method area (metaspace after JDK1.8) resources, but each thread has its own program counter , virtual machine stack and Local method stack.

Summary: Threads are processes divided into smaller running units. The biggest difference between threads and processes is that each process is basically independent, but each thread is not necessarily, because threads in the same process are very likely to affect each other. Thread execution overhead is small, but it is not conducive to resource management and protection; on the contrary, processes

The following is an expansion of this knowledge point!

Let’s think about this question: Why are

program counter, virtual machine stack and local method stack private to threads? Why are the heap and method area shared by threads?

2.2. Why is the program counter private?

The program counter mainly has the following two functions:

    The bytecode interpreter reads instructions sequentially by changing the program counter to achieve code flow control, such as sequential execution, selection, looping, and exception handling.
  1. In the case of multi-threading, the program counter is used to record the execution position of the current thread, so that when the thread is switched back, it can be known where the thread ran last time.
It should be noted that if the native method is executed, the program counter records an undefined address. Only when Java code is executed, the program counter records the address of the next instruction.

Therefore, the purpose of keeping the program counter private is mainly to

restore it to the correct execution position after switching threads .

2.3. Why are the virtual machine stack and local method stack private?

  • Virtual machine stack: When each Java method is executed, a stack frame will be created to store information such as local variable tables, operand stacks, and constant pool references. The process from method invocation to completion of execution corresponds to the process of pushing and popping a stack frame into the Java virtual machine stack.
  • Local method stack: The role played by the virtual machine stack is very similar, the difference is: The virtual machine stack serves the virtual machine to execute Java methods (that is, bytecode) , and the local method stack serves the Native methods used by the virtual machine. Combined with the Java virtual machine stack in the HotSpot virtual machine.

So, in order to ensure that local variables in the thread are not accessed by other threads , the virtual machine stack and local method stack are thread private.

2.4. A brief understanding of the heap and method area in one sentence

The heap and method area are resources shared by all threads, where the heap is the The largest piece of memory is mainly used to store newly created objects (all objects are allocated memory here). The method area is mainly used to store loaded class information, constants, static variables, code compiled by the just-in-time compiler and other data. .

3. Talk about the difference between concurrency and parallelism?

  • Concurrency: In the same time period, multiple All tasks are being executed (not necessarily executed at the same time per unit time);
  • Parallel: Multiple tasks are executed at the same time per unit time.

4. Why use multi-threading?

Let’s talk about it in general:

  • From the bottom of the computer: Threads can be compared to lightweight processes, which are the smallest units of program execution. The cost of switching and scheduling between threads is far less than that of processes. In addition, the multi-core CPU era means that multiple threads can run simultaneously, which reduces the overhead of thread context switching.
  • From the perspective of contemporary Internet development trends: Today’s systems often require millions or even tens of millions of concurrency, and multi-threaded concurrent programming is the basis for developing high-concurrency systems. , using multi-threading mechanisms can greatly improve the overall concurrency and performance of the system.

Let’s go deeper into the bottom layer of the computer:

  • Single-core era: In the single-core era, multi-threading was mainly to improve the CPU and IO equipment comprehensive utilization rate. For example: when there is only one thread, the IO device will be idle when the CPU is performing calculations; the CPU will be idle when performing IO operations. We can simply say that the utilization rate of both is currently around 50%. But it's different when there are two threads. When one thread performs CPU calculations, the other thread can perform IO operations, so that the utilization of the two can reach 100% under ideal circumstances.
  • Multi-core era: Multi-threading in the multi-core era is mainly to improve CPU utilization. For example: If we want to calculate a complex task, if we only use one thread, only one CPU core of the CPU will be utilized, but creating multiple threads can allow multiple CPU cores to be utilized, which improves the performance CPU utilization.

5. What problems may be caused by using multi-threading?

The purpose of concurrent programming is to improve the execution efficiency of the program Improve program running speed, but concurrent programming does not always improve program running speed, and concurrent programming may encounter many problems, such as: memory leaks, context switches, deadlocks, and idle resources limited by hardware and software. question.

6. Talk about the life cycle and status of threads?

A Java thread can only be in the following at a specified moment in its running life cycle One of the 6 different states (image source "The Art of Java Concurrent Programming" Section 4.1.4).

Java concurrency basics common interview questions (summary)

#Threads are not fixed in a certain state during the life cycle but switch between different states as the code is executed. The state changes of Java threads are shown in the figure below (picture source "The Art of Java Concurrent Programming" Section 4.1.4):

Java concurrency basics common interview questions (summary)

As can be seen from the above figure: after the thread is created, it will In the NEW (new) state, it starts running after calling the start() method. The thread is in the READY (runnable) state at this time. A thread in the runnable state is in the RUNNING state after it obtains the CPU time slice (timeslice).

操作系統(tǒng)隱藏 Java 虛擬機(jī)(JVM)中的 RUNNABLE 和 RUNNING 狀態(tài),它只能看到 RUNNABLE 狀態(tài)(圖源:HowToDoInJavaJava Thread Life Cycle and Thread States),所以 Java 系統(tǒng)一般將這兩個狀態(tài)統(tǒng)稱為 RUNNABLE(運(yùn)行中) 狀態(tài) 。

Java concurrency basics common interview questions (summary)

當(dāng)線程執(zhí)行 wait()方法之后,線程進(jìn)入 WAITING(等待) 狀態(tài)。進(jìn)入等待狀態(tài)的線程需要依靠其他線程的通知才能夠返回到運(yùn)行狀態(tài),而 TIME_WAITING(超時等待) 狀態(tài)相當(dāng)于在等待狀態(tài)的基礎(chǔ)上增加了超時限制,比如通過 sleep(long millis)方法或 wait(long millis)方法可以將 Java 線程置于 TIMED WAITING 狀態(tài)。當(dāng)超時時間到達(dá)后 Java 線程將會返回到 RUNNABLE 狀態(tài)。當(dāng)線程調(diào)用同步方法時,在沒有獲取到鎖的情況下,線程將會進(jìn)入到 BLOCKED(阻塞) 狀態(tài)。線程在執(zhí)行 Runnable 的 run() 方法之后將會進(jìn)入到 TERMINATED(終止) 狀態(tài)。

7. 什么是上下文切換?

多線程編程中一般線程的個數(shù)都大于 CPU 核心的個數(shù),而一個 CPU 核心在任意時刻只能被一個線程使用,為了讓這些線程都能得到有效執(zhí)行,CPU 采取的策略是為每個線程分配時間片并輪轉(zhuǎn)的形式。當(dāng)一個線程的時間片用完的時候就會重新處于就緒狀態(tài)讓給其他線程使用,這個過程就屬于一次上下文切換。

概括來說就是:當(dāng)前任務(wù)在執(zhí)行完 CPU 時間片切換到另一個任務(wù)之前會先保存自己的狀態(tài),以便下次再切換回這個任務(wù)時,可以再加載這個任務(wù)的狀態(tài)。任務(wù)從保存到再加載的過程就是一次上下文切換。

上下文切換通常是計算密集型的。也就是說,它需要相當(dāng)可觀的處理器時間,在每秒幾十上百次的切換中,每次切換都需要納秒量級的時間。所以,上下文切換對系統(tǒng)來說意味著消耗大量的 CPU 時間,事實(shí)上,可能是操作系統(tǒng)中時間消耗最大的操作。

Linux 相比與其他操作系統(tǒng)(包括其他類 Unix 系統(tǒng))有很多的優(yōu)點(diǎn),其中有一項(xiàng)就是,其上下文切換和模式切換的時間消耗非常少。

8. 什么是線程死鎖?如何避免死鎖?

8.1. 認(rèn)識線程死鎖

多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放。由于線程被無限期地阻塞,因此程序不可能正常終止。

如下圖所示,線程 A 持有資源 2,線程 B 持有資源 1,他們同時都想申請對方的資源,所以這兩個線程就會互相等待而進(jìn)入死鎖狀態(tài)。

Java concurrency basics common interview questions (summary)

下面通過一個例子來說明線程死鎖,代碼模擬了上圖的死鎖的情況 (代碼來源于《并發(fā)編程之美》):

public?class?DeadLockDemo?{
????private?static?Object?resource1?=?new?Object();//資源?1
????private?static?Object?resource2?=?new?Object();//資源?2

????public?static?void?main(String[]?args)?{
????????new?Thread(()?->?{
????????????synchronized?(resource1)?{
????????????????System.out.println(Thread.currentThread()?+?"get?resource1");
????????????????try?{
????????????????????Thread.sleep(1000);
????????????????}?catch?(InterruptedException?e)?{
????????????????????e.printStackTrace();
????????????????}
????????????????System.out.println(Thread.currentThread()?+?"waiting?get?resource2");
????????????????synchronized?(resource2)?{
????????????????????System.out.println(Thread.currentThread()?+?"get?resource2");
????????????????}
????????????}
????????},?"線程?1").start();

????????new?Thread(()?->?{
????????????synchronized?(resource2)?{
????????????????System.out.println(Thread.currentThread()?+?"get?resource2");
????????????????try?{
????????????????????Thread.sleep(1000);
????????????????}?catch?(InterruptedException?e)?{
????????????????????e.printStackTrace();
????????????????}
????????????????System.out.println(Thread.currentThread()?+?"waiting?get?resource1");
????????????????synchronized?(resource1)?{
????????????????????System.out.println(Thread.currentThread()?+?"get?resource1");
????????????????}
????????????}
????????},?"線程?2").start();
????}
}

Output

Thread[線程?1,5,main]get?resource1
Thread[線程?2,5,main]get?resource2
Thread[線程?1,5,main]waiting?get?resource2
Thread[線程?2,5,main]waiting?get?resource1

線程 A 通過 synchronized (resource1) 獲得 resource1 的監(jiān)視器鎖,然后通過 Thread.sleep(1000);讓線程 A 休眠 1s 為的是讓線程 B 得到執(zhí)行然后獲取到 resource2 的監(jiān)視器鎖。線程 A 和線程 B 休眠結(jié)束了都開始企圖請求獲取對方的資源,然后這兩個線程就會陷入互相等待的狀態(tài),這也就產(chǎn)生了死鎖。上面的例子符合產(chǎn)生死鎖的四個必要條件。

學(xué)過操作系統(tǒng)的朋友都知道產(chǎn)生死鎖必須具備以下四個條件:

  1. 互斥條件:該資源任意一個時刻只由一個線程占用。
  2. 請求與保持條件:一個進(jìn)程因請求資源而阻塞時,對已獲得的資源保持不放。
  3. 不剝奪條件:線程已獲得的資源在末使用完之前不能被其他線程強(qiáng)行剝奪,只有自己使用完畢后才釋放資源。
  4. 循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。

8.2. 如何避免線程死鎖?

我們只要破壞產(chǎn)生死鎖的四個條件中的其中一個就可以了。

破壞互斥條件

這個條件我們沒有辦法破壞,因?yàn)槲覀冇面i本來就是想讓他們互斥的(臨界資源需要互斥訪問)。

破壞請求與保持條件

一次性申請所有的資源。

破壞不剝奪條件

占用部分資源的線程進(jìn)一步申請其他資源時,如果申請不到,可以主動釋放它占有的資源。

破壞循環(huán)等待條件

靠按序申請資源來預(yù)防。按某一順序申請資源,釋放資源則反序釋放。破壞循環(huán)等待條件。

我們對線程 2 的代碼修改成下面這樣就不會產(chǎn)生死鎖了。

????????new?Thread(()?->?{
????????????synchronized?(resource1)?{
????????????????System.out.println(Thread.currentThread()?+?"get?resource1");
????????????????try?{
????????????????????Thread.sleep(1000);
????????????????}?catch?(InterruptedException?e)?{
????????????????????e.printStackTrace();
????????????????}
????????????????System.out.println(Thread.currentThread()?+?"waiting?get?resource2");
????????????????synchronized?(resource2)?{
????????????????????System.out.println(Thread.currentThread()?+?"get?resource2");
????????????????}
????????????}
????????},?"線程?2").start();

Output

Thread[線程?1,5,main]get?resource1
Thread[線程?1,5,main]waiting?get?resource2
Thread[線程?1,5,main]get?resource2
Thread[線程?2,5,main]get?resource1
Thread[線程?2,5,main]waiting?get?resource2
Thread[線程?2,5,main]get?resource2

Process?finished?with?exit?code?0

我們分析一下上面的代碼為什么避免了死鎖的發(fā)生?

線程 1 首先獲得到 resource1 的監(jiān)視器鎖,這時候線程 2 就獲取不到了。然后線程 1 再去獲取 resource2 的監(jiān)視器鎖,可以獲取到。然后線程 1 釋放了對 resource1、resource2 的監(jiān)視器鎖的占用,線程 2 獲取到就可以執(zhí)行了。這樣就破壞了破壞循環(huán)等待條件,因此避免了死鎖。

9. 說說 sleep() 方法和 wait() 方法區(qū)別和共同點(diǎn)?

  • 兩者最主要的區(qū)別在于:sleep 方法沒有釋放鎖,而 wait 方法釋放了鎖
  • 兩者都可以暫停線程的執(zhí)行。
  • Wait 通常被用于線程間交互/通信,sleep 通常被用于暫停執(zhí)行。
  • wait() 方法被調(diào)用后,線程不會自動蘇醒,需要別的線程調(diào)用同一個對象上的 notify() 或者 notifyAll() 方法。sleep() 方法執(zhí)行完成后,線程會自動蘇醒。或者可以使用wait(long timeout)超時后線程會自動蘇醒。

10. 為什么我們調(diào)用 start() 方法時會執(zhí)行 run() 方法,為什么我們不能直接調(diào)用 run() 方法?

這是另一個非常經(jīng)典的 java 多線程面試問題,而且在面試中會經(jīng)常被問到。很簡單,但是很多人都會答不上來!

new 一個 Thread,線程進(jìn)入了新建狀態(tài);調(diào)用 start() 方法,會啟動一個線程并使線程進(jìn)入了就緒狀態(tài),當(dāng)分配到時間片后就可以開始運(yùn)行了。 start() 會執(zhí)行線程的相應(yīng)準(zhǔn)備工作,然后自動執(zhí)行 run() 方法的內(nèi)容,這是真正的多線程工作。 而直接執(zhí)行 run() 方法,會把 run 方法當(dāng)成一個 main 線程下的普通方法去執(zhí)行,并不會在某個線程中執(zhí)行它,所以這并不是多線程工作。

總結(jié): 調(diào)用 start 方法方可啟動線程并使線程進(jìn)入就緒狀態(tài),而 run 方法只是 thread 的一個普通方法調(diào)用,還是在主線程里執(zhí)行。

推薦教程:java教程

The above is the detailed content of Java concurrency basics common interview questions (summary). For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1488
72
VSCode settings.json location VSCode settings.json location Aug 01, 2025 am 06:12 AM

The settings.json file is located in the user-level or workspace-level path and is used to customize VSCode settings. 1. User-level path: Windows is C:\Users\\AppData\Roaming\Code\User\settings.json, macOS is /Users//Library/ApplicationSupport/Code/User/settings.json, Linux is /home//.config/Code/User/settings.json; 2. Workspace-level path: .vscode/settings in the project root directory

How to handle transactions in Java with JDBC? How to handle transactions in Java with JDBC? Aug 02, 2025 pm 12:29 PM

To correctly handle JDBC transactions, you must first turn off the automatic commit mode, then perform multiple operations, and finally commit or rollback according to the results; 1. Call conn.setAutoCommit(false) to start the transaction; 2. Execute multiple SQL operations, such as INSERT and UPDATE; 3. Call conn.commit() if all operations are successful, and call conn.rollback() if an exception occurs to ensure data consistency; at the same time, try-with-resources should be used to manage resources, properly handle exceptions and close connections to avoid connection leakage; in addition, it is recommended to use connection pools and set save points to achieve partial rollback, and keep transactions as short as possible to improve performance.

Mastering Dependency Injection in Java with Spring and Guice Mastering Dependency Injection in Java with Spring and Guice Aug 01, 2025 am 05:53 AM

DependencyInjection(DI)isadesignpatternwhereobjectsreceivedependenciesexternally,promotingloosecouplingandeasiertestingthroughconstructor,setter,orfieldinjection.2.SpringFrameworkusesannotationslike@Component,@Service,and@AutowiredwithJava-basedconfi

python itertools combinations example python itertools combinations example Jul 31, 2025 am 09:53 AM

itertools.combinations is used to generate all non-repetitive combinations (order irrelevant) that selects a specified number of elements from the iterable object. Its usage includes: 1. Select 2 element combinations from the list, such as ('A','B'), ('A','C'), etc., to avoid repeated order; 2. Take 3 character combinations of strings, such as "abc" and "abd", which are suitable for subsequence generation; 3. Find the combinations where the sum of two numbers is equal to the target value, such as 1 5=6, simplify the double loop logic; the difference between combinations and arrangement lies in whether the order is important, combinations regard AB and BA as the same, while permutations are regarded as different;

python pytest fixture example python pytest fixture example Jul 31, 2025 am 09:35 AM

fixture is a function used to provide preset environment or data for tests. 1. Use the @pytest.fixture decorator to define fixture; 2. Inject fixture in parameter form in the test function; 3. Execute setup before yield, and then teardown; 4. Control scope through scope parameters, such as function, module, etc.; 5. Place the shared fixture in conftest.py to achieve cross-file sharing, thereby improving the maintainability and reusability of tests.

Understanding the Java Virtual Machine (JVM) Internals Understanding the Java Virtual Machine (JVM) Internals Aug 01, 2025 am 06:31 AM

TheJVMenablesJava’s"writeonce,runanywhere"capabilitybyexecutingbytecodethroughfourmaincomponents:1.TheClassLoaderSubsystemloads,links,andinitializes.classfilesusingbootstrap,extension,andapplicationclassloaders,ensuringsecureandlazyclassloa

How to work with Calendar in Java? How to work with Calendar in Java? Aug 02, 2025 am 02:38 AM

Use classes in the java.time package to replace the old Date and Calendar classes; 2. Get the current date and time through LocalDate, LocalDateTime and LocalTime; 3. Create a specific date and time using the of() method; 4. Use the plus/minus method to immutably increase and decrease the time; 5. Use ZonedDateTime and ZoneId to process the time zone; 6. Format and parse date strings through DateTimeFormatter; 7. Use Instant to be compatible with the old date types when necessary; date processing in modern Java should give priority to using java.timeAPI, which provides clear, immutable and linear

Google Chrome cannot open local files Google Chrome cannot open local files Aug 01, 2025 am 05:24 AM

ChromecanopenlocalfileslikeHTMLandPDFsbyusing"Openfile"ordraggingthemintothebrowser;ensuretheaddressstartswithfile:///;2.SecurityrestrictionsblockAJAX,localStorage,andcross-folderaccessonfile://;usealocalserverlikepython-mhttp.server8000tor

See all articles