Java thread related knowledge points

Popular knowledge points related to Java threads

 

1) What is a thread?

Thread is the smallest unit that the operating system can perform operation scheduling. It is included in the process and is the actual operation unit in the process. Programmers can use it for multiprocessor programming, and you can use multithreading to speed up computationally intensive tasks. For example, if it takes 100 milliseconds for one thread to complete a task, it only takes 10 milliseconds to complete the task with ten threads. Java's excellent support for multithreading at the language level is also a great selling point.

 

2) What is the difference between a thread and a process?

Threads are a subset of processes, and a process can have many threads, each executing a different task in parallel. Different processes use different memory spaces, and all threads share the same memory space. Don't confuse it with stack memory, each thread has a separate stack memory for storing local data.

 

3) How to implement threads in Java?

At the language level there are two ways. An instance of the java.lang.Thread class is a thread, but it needs to call the java.lang.Runnable interface to execute. Since the thread class itself is the Runnable interface to call, you can inherit the java.lang.Thread class or directly call the Runnable interface to reset Write the run() method to implement the thread.

 

4) Use Runnable or Thread?

This question is a follow-up to the previous question. Everyone knows that we can implement threads by inheriting the Thread class or calling the Runnable interface. The question is, which method is better? When to use it? This question is easy to answer if you know that Java does not support multiple inheritance of classes, but allows you to call multiple interfaces. So if you want to inherit other classes, of course, call the Runnable interface.

 

6) What is the difference between start() and run() methods in Thread class?

This question is often asked, but it still distinguishes the interviewee's understanding of the Java threading model. The start() method is used to start the newly created thread, and start() internally calls the run() method, which is different from calling the run() method directly. When you call the run() method, it will only be called in the original thread. If no new thread is started, the start() method will start a new thread.

 

7) What is the difference between Runnable and Callable in Java?

Both Runnable and Callable represent tasks to be executed in different threads. Runnable has been available since JDK1.0, and Callable was added in JDK1.5. The main difference between them is that Callable's call() method can return values ​​and throw exceptions, while Runnable's run() method does not have these functions. Callable can return a Future object loaded with the result of the calculation.

 

8) What is the difference between CyclicBarrier and CountDownLatch in Java?

Both CyclicBarrier and CountDownLatch can be used to make a group of threads wait for other threads. Unlike CyclicBarrier, CountdownLatch cannot be reused.

 

9) What is the Java memory model?

The Java memory model specifies and guides Java programs to behave deterministically across different memory architectures, CPUs, and operating systems. It is especially important in multithreaded situations. The Java memory model guarantees that changes made by one thread can be seen by other threads, and there is a happen-before relationship between them. This relationship defines some rules to allow programmers to think more clearly when programming concurrently. For example, a happen-before relationship ensures that:

• Code within a thread can be executed sequentially, which is called the program order rule.

• For the same lock, an unlocking operation must occur before another locking operation that occurs after time, also known as monitor locking rules.

• The previous write operation to volatile precedes the subsequent read operation of volatile, also known as the volatile variable rule.

• Any operation within a thread must follow the thread's start() call, also known as thread start rules.

• All operations of a thread will be terminated before the thread, the thread termination rules.

• The finalization operation of an object must be completed after the object is constructed, also called the object finalization rule.

• Deliverability

I strongly recommend that you read Chapter 16 of Java Concurrent Programming in Practice to deepen your understanding of the Java memory model.

 

10) What is a volatile variable in Java?

volatile is a special modifier that can only be used by member variables. In the absence of synchronization classes in Java concurrent programs, multi-thread operations on member variables are transparent to other threads. Volatile variables can guarantee that the next read operation will occur after the previous write operation, which is the volatile variable rule in the previous question.

 

11) What is thread safety? Is Vector a thread safe class? (see here for details)

If your code is in a process with multiple threads running at the same time, these threads may be running this code at the same time. If the result of each run is the same as the result of a single-threaded run, and the values ​​of other variables are the same as expected, it is thread-safe. The same instance of a thread-safe counter class will not fail miscalculation if it is used by multiple threads. Obviously you can divide collection classes into two groups, thread-safe and non-thread-safe. Vector is thread-safe using synchronized methods, while ArrayList like it is not thread-safe.

 

12) What is a race condition in Java? Give an example.

Race conditions can lead to some bugs in the program in the case of concurrency. When multiple threads compete for some resources, race conditions will occur. If the first program to be executed fails to compete and is executed later, then the entire program will have some uncertain bugs. Such bugs are hard to spot and recur because of random competition between threads.

 

13) How to stop a thread in Java?

Java provides a rich API but no API for stopping threads. JDK 1.0 originally had some control methods like stop(), suspend() and resume() but they were deprecated in subsequent JDK versions due to potential deadlock threats, after which the Java API designers did not provide one Compatible and thread-safe method to stop a thread. When the run() or call() method finishes executing, the thread will automatically terminate. If you want to manually terminate a thread, you can use a volatile boolean variable to exit the loop of the run() method or cancel the task to interrupt the thread.

 

14) What happens when an exception occurs while a thread is running?

This is a very tricky Java interview question I encountered in an interview. Simply put, if the exception is not caught, the thread will stop executing. Thread.UncaughtExceptionHandler is an inline interface for handling sudden interruption of threads caused by uncaught exceptions. When an uncaught exception will cause the thread to be interrupted, the JVM will use Thread.getUncaughtExceptionHandler() to query the thread's UncaughtExceptionHandler and pass the thread and exception as parameters to the handler's uncaughtException() method for processing.

 

15) How to share data between two threads?

You can do this by sharing objects, or using concurrent data structures like blocking queues. This tutorial "Java Inter-Thread Communication" (which involves sharing objects between two threads) implements the producer-consumer model with the wait and notify methods.

 

16) What is the difference between notify and notifyAll in Java?

This is another tricky problem, because multiple threads can wait for a single-monitored lock, and the designers of the Java API provided some methods to notify them when the wait condition changed, but these methods are not fully implemented. The notify() method cannot wake up a specific thread, so it is only useful when a thread is waiting. And notifyAll() wakes up all threads and allows them to contend for the lock, ensuring that at least one thread can continue to run.

 

17) Why wait, notify and notifyAll are not in thread class?

This is a design-related question that looks at the interviewer's perception of existing systems and things that are ubiquitous but don't seem reasonable. When answering these questions, you should explain why it makes sense to put these methods in the Object class, and why not to put them in the Thread class. An obvious reason is that the locks provided by JAVA are object-level rather than thread-level, and each object has a lock, which is obtained by a thread. If the thread needs to wait for some lock then it makes sense to call the wait() method on the object. If the wait() method is defined in the Thread class, it is not obvious which lock the thread is waiting for. Simply put, since wait, notify and notifyAll are lock-level operations, they are defined in the Object class because locks belong to objects.

 

18) What are ThreadLocal variables?

ThreadLocal is a special kind of variable in Java. Each thread has a ThreadLocal, that is, each thread has its own independent variable, and the race condition is completely eliminated. It's a good way to get thread-safe for creating expensive objects, for example you can use ThreadLocal to make SimpleDateFormat thread-safe, because that class is expensive to create and needs to create a different instance for each call so it's not worth it in local scope Using it, if you provide each thread with a unique copy of the variable, it will greatly improve efficiency. First, the creation of expensive objects is reduced through reuse. Second, you get thread safety without using expensive synchronization or immutability. Another good example of thread-local variables is the ThreadLocalRandom class, which reduces the number of expensive Random objects to create in a multithreaded environment.

 

19) What is FutureTask?

In Java concurrent programs, FutureTask represents an asynchronous operation that can be canceled. It has methods for starting and canceling operations, querying whether the operation is completed, and retrieving the operation results. The result can only be retrieved when the operation is complete, and the get method will block if the operation has not yet completed. A FutureTask object can wrap objects that call Callable and Runnable. Since FutureTask also calls the Runnable interface, it can be submitted to Executor for execution.

 

20) What is the difference between interrupted and isInterruptedd methods in Java?

The main difference between interrupted() and isInterrupted() is that the former will clear the interrupted state while the latter will not. The interrupt mechanism of Java multi-threading is implemented with internal flags. Calling Thread.interrupt() to interrupt a thread will set the interrupt flag to true. When the interrupted thread calls the static method Thread.interrupted() to check the interrupted state, the interrupted state is cleared. The non-static method isInterrupted() is used to query the interrupted status of other threads and does not change the interrupted status flag. Simply put, any method that throws an InterruptedException will clear the interrupted state. In any case, it is possible for a thread's interrupt status to be changed by other threads calling interrupts.

 

21) Why wait and notify methods are called in synchronized blocks?

Mainly because the Java API mandates this, and if you don't, your code will throw an IllegalMonitorStateException. Another reason is to avoid race conditions between wait and notify.

 

22) Why should you check for wait conditions in loops?

Threads in the waiting state may receive false alarms and spurious wakeups, and if the waiting condition is not checked in the loop, the program will exit without meeting the end condition. Therefore, when a waiting thread wakes up, its original waiting state cannot be considered to be still valid, it may change between the time after the notify() method call and before the waiting thread wakes up. This is why using the wait() method in a loop works better, you can create a template in Eclipse to call wait and notify to give it a try.

 

23) What is the difference between synchronized collections and concurrent collections in Java?

Both synchronized collections and concurrent collections provide suitable thread-safe collections for multithreading and concurrency, but concurrent collections are more scalable. Before Java 1.5, programmers only used synchronized collections, which would cause contention when multiple threads were concurrent, hindering the scalability of the system. Java 5 introduced concurrent collections like ConcurrentHashMap, which not only provide thread safety but also improve scalability with modern techniques such as lock separation and internal partitioning.

 

24) What is the difference between heap and stack in Java?

Why is this question classified as a multithreading and concurrency interview question? Because the stack is a memory area closely related to threads. Each thread has its own stack memory for storing local variables, method parameters and stack calls. Variables stored in one thread are invisible to other threads. The heap is a common memory area shared by all threads. Objects are created in the heap. In order to improve efficiency, the thread will get a cache from the heap to its own stack. If multiple threads use this variable, it may cause problems. At this time, the volatile variable can play a role. It requires the thread from the main Read the value of the variable from the memory.

 

25) What is a thread pool? Why use it?

Creating a thread takes expensive resources and time. If a thread is created before a task arrives, the response time will be longer, and a process can create a limited number of threads. In order to avoid these problems, a number of threads are created to respond to processing when the program starts. They are called thread pools, and the threads in them are called worker threads. Starting from JDK1.5, the Java API provides the Executor framework so that you can create different thread pools. For example, a single thread pool, which processes one task at a time; a fixed number of thread pools or a cached thread pool (a scalable thread pool suitable for programs with many short-lived tasks).

 

26) How to write code to solve the producer consumer problem?

In reality, many thread problems you solve belong to the producer-consumer model, that is, a thread produces tasks for other threads to consume. You must know how to communicate between threads to solve this problem. The lower-level way is to use wait and notify to solve this problem, and the better way is to use Semaphore or BlockingQueue to implement the producer-consumer model.

 

27) How to avoid deadlock?

 

Deadlock in Java Multithreading

Deadlock refers to a phenomenon in which two or more processes are waiting for each other due to competition for resources during the execution process. If there is no external force, they will not be able to advance. This is a serious problem, because deadlocks can make your program hang and fail to complete tasks. For a deadlock to occur, the following four conditions must be met:

• Mutual exclusion condition: A resource can only be used by one process at a time.

• Request and hold conditions: When a process is blocked by requesting resources, it will hold on to the obtained resources.

• No deprivation condition: The resource that the process has obtained cannot be forcibly deprived until it is used up.

•Circular waiting condition: A kind of circular waiting resource relationship is formed between several processes.

The easiest way to avoid deadlock is to prevent the circular waiting condition, set flags and sort all resources in the system, and stipulate that all processes applying for resources must operate in a certain order (ascending or descending) to avoid deadlock.

 

28) What is the difference between livelock and deadlock in Java?

This is an extension of the previous question. Livelock is similar to deadlock, except that the state of the thread or process in livelock is constantly changing. Livelock can be considered a special kind of starvation. A realistic example of a livelock is when two people meet in a narrow corridor, and both try to avoid each other to allow each other to pass, but because the direction of avoidance is the same, no one can pass the corridor in the end. Simply put, the main difference between livelock and deadlock is that the state of the former process can change but cannot continue to execute.

 

29) How to check if a thread owns the lock?

I never knew we could detect if a thread owns a lock until I did a phone interview. There is a method in java.lang.Thread called holdsLock() which returns true if and only if the current thread holds a lock on a specific object.

 

30) How do you get thread stack in Java?

There are multiple ways to get the thread stack of a Java process for different operating systems. When you get the thread stack, the JVM will save the state of all threads to a log file or output to the console. On Windows you can use the Ctrl + Break key combination to get the thread stack, on Linux use the kill -3 command. You can also use the jstack tool to get it, it operates on the thread id, and you can use the jps tool to find the id.

 

31) Which parameter in the JVM is used to control the small stack of the thread

The problem is simple, the -Xss parameter is used to control the stack size of the thread.

 

32) What is the difference between synchronized and ReentrantLock in Java?

Java for a long time in the past can only achieve mutual exclusion through the synchronized keyword, which has some disadvantages. For example, you can't extend methods or block boundaries outside the lock, you can't cancel halfway through trying to acquire a lock, etc. Java 5 addresses these issues by providing more sophisticated controls through the Lock interface. The ReentrantLock class implements Lock, which has the same concurrency and memory semantics as synchronized and which is also extensible.

 

33) There are three threads T1, T2, T3, how to ensure that they are executed in order?

In multithreading there are various ways to make threads execute in a specific order, you can use the join() method of the thread class to start another thread in one thread, and the other thread finishes executing the thread. To ensure the order of the three threads you should start the last one first (T3 calls T2, T2 calls T1), so that T1 finishes first and T3 finishes last.

 

34) What does the yield method in the Thread class do?

The Yield method can suspend the currently executing thread object and let other threads with the same priority execute. It is a static method and only guarantees that the current thread will give up the CPU usage and cannot guarantee that other threads will be able to occupy the CPU. The thread that executes yield() may be executed again immediately after entering the suspended state.

 

35) What is the concurrency of ConcurrentHashMap in Java?

ConcurrentHashMap divides the actual map into several parts to achieve its scalability and thread safety. This division is obtained using the degree of concurrency, an optional parameter to the constructor of the ConcurrentHashMap class, with a default value of 16, to avoid contention in multi-threaded situations.

 

36) What is Semaphore in Java?

Semaphore in Java is a new synchronization class which is a counting signal. Conceptually, a semaphore maintains a set of permissions. If necessary, each acquire() is blocked until a license is available, and then the license is acquired. Each release() adds a permission, potentially releasing a blocking acquirer. However, instead of using the actual license object, Semaphore just counts the number of available licenses and acts accordingly. Semaphores are often used in multithreaded code, such as database connection pooling.

 

37) If the thread pool queue is full when you submit the task. What will happen from time to time?

This is a tricky question, and many programmers will think that the task will block until the thread pool queue becomes available. In fact, if a task cannot be scheduled for execution then ThreadPoolExecutor's submit() method will throw a RejectedExecutionException.

 

38) What is the difference between submit() and execute() methods in Java thread pool?

Both methods can submit tasks to the thread pool. The return type of the execute() method is void, which is defined in the Executor interface, and the submit() method can return a Future object that holds the calculation result, which is defined in the ExecutorService interface. It extends the Executor interface, other thread pool classes like ThreadPoolExecutor and ScheduledThreadPoolExecutor have these methods.

 

39) What is a blocking method?

The blocking method means that the program will wait for the method to complete and do nothing else. The accept() method of ServerSocket is to wait for the client to connect. The blocking here means that before the call result is returned, the current thread will be suspended and will not return until the result is obtained. In addition, there are asynchronous and non-blocking methods that return before the task is completed.

 

40) Is Swing thread safe? Why?

You can answer with certainty that Swing is not thread-safe, but you should explain the reason for this answer even if the interviewer doesn't ask you why. When we say that swing is not thread-safe, we often refer to its components. These components cannot be modified in multiple threads. All updates to GUI components must be completed in the AWT thread. Swing provides synchronous and asynchronous callback methods. to update.

 

41) What is the difference between invokeAndWait and invokeLater in Java?

These two methods are provided by the Swing API for Java developers to update GUI components from the current thread rather than the event dispatch thread. InvokeAndWait() synchronously updates GUI components, such as a progress bar. Once the progress is updated, the progress bar should also be changed accordingly. If the progress is tracked by multiple threads, call the invokeAndWait() method to request the event dispatch thread to update the component accordingly. The invokeLater() method calls the update component asynchronously.

 

42) Which methods in Swing API are thread safe?

This question also mentions swing and thread safety. Although components are not thread-safe, there are some methods that can be called safely by multiple threads, such as repaint(), revalidate(). JTextComponent's setText() method and JTextArea's insert() and append() methods are also thread-safe.

 

43) How to create Immutable object in Java?

This problem doesn't seem to have much to do with multithreading, but immutability helps simplify already complex concurrent programs. Immutable objects can be shared without synchronization, reducing the synchronization overhead of concurrent access to the object. However, Java does not have the @Immutable annotation. To create an immutable class, you must implement the following steps: initialize all members through the constructor, do not provide setter methods for variables, declare all members as private, so that direct To access these members, in the getter method, do not directly return the object itself, but clone the object and return a copy of the object.

 

44) What is ReadWriteLock in Java?

Generally speaking, read-write locks are the result of lock separation techniques used to improve the performance of concurrent programs. ReadWriteLock in Java is an interface added in Java 5. A ReadWriteLock maintains a pair of associated locks, one for read-only operations and one for writing. In the absence of writer threads, a reader lock may be held by multiple reader threads at the same time. Write locks are exclusive, you can use ReentrantReadWriteLock in JDK to implement this rule, which supports up to 65535 write locks and 65535 read locks.

 

45) What is busy loop in multithreading?

A busy loop is when a programmer uses a loop to make a thread wait, unlike the traditional methods wait(), sleep() or yield() which all give up CPU control, while a busy loop does not give up the CPU, it just runs an empty loop. The purpose of this is to preserve the CPU cache, on a multi-core system, a waiting thread may wake up and run on another core, which will rebuild the cache. It can be used to avoid rebuilding the cache and reduce waiting time for rebuilds.

 

46) What is the difference between volatile variable and atomic variable?

This is an interesting question. First, volatile variables and atomic variables look similar, but function differently. Volatile variables can ensure look-ahead relationships, that is, write operations will occur before subsequent read operations, but it does not guarantee atomicity. For example, if the count variable is modified with volatile, then the count++ operation is not atomic. The atomic method provided by the AtomicInteger class can make this operation atomic. For example, the getAndIncrement() method will atomically perform an incremental operation and add one to the current value. Other data types and reference variables can also perform similar operations.

 

47) What happens if a thread inside a synchronized block throws an exception?

This question has pitted many Java programmers. If you can think of the clue of whether the lock is released or not, there is a little hope that you will get it right. Whether your synchronized block exits normally or abnormally, the thread inside will release the lock, so I prefer the lock interface

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326864912&siteId=291194637