Java Multi-threading, concurrent programming Knowledge Point Summary

Source: Internet
Author: User
Tags thread stop visibility

1, the state of the thread

1.1 Create threads in two ways, interface and thread classes. The advantage of using the interface: Better embody the object-oriented idea, can avoid the limitations of Java's single inheritance;
Enhance the robustness of the program, the code can be shared by multiple threads, the code and data are independent, (synchronization problems) suitable for multiple threads of the same program code to handle the same resource situation.


1.2 Thread ready to run the start () method for scheduling.


1.3 Interrupt for Thread

It is important to note that if you simply call the interrupt () method, the thread is not actually interrupted and will continue to execute.


1.4. Thread hangs and resumes (hangs also has object lock, deadlock)
The correct way to suspend and resume a thread is to have the thread hang in a secure location by setting a flag bit


1.5 using the Jion method for synchronous running with multithreaded simulations, mthread.jion () indicates that the thread that called it is running after the threads have finished running.


1.6 Sleep Sleep

When the thread executes Thread.Sleep (), it blocks until the specified millisecond time, or the block is interrupted by another thread;


1.7stop Thread Stop

The Stop method abruptly terminates the thread (there must be some appropriate justification for holding these locks-perhaps to prevent other threads from accessing data that is not yet in a consistent state.
Sudden release of locks may cause data in some objects to be in an inconsistent state


1.8 threads can block in four states:


When the thread executes Thread.Sleep (), it blocks until the specified millisecond time, or the block is interrupted by another thread;


When a thread encounters a wait () statement, it blocks until it receives notification (notify ()), is interrupted, or passes a specified millisecond (if the timeout value is set)
There are several ways to block a thread from different I/O. One common way is the read () method of InputStream, which blocks until a byte of data is read from the stream, it can block indefinitely, and therefore cannot specify a time-out
A thread can also block an exclusive access that waits to acquire an object lock (that is, to wait for a lock that the synchronized statement must have blocked).


2. Types of threads

Four scenarios in which the daemon thread and thread are blocked
There are two types of threads in Java: User thread, Daemon thread (daemon thread)
The user can set the current thread as the daemon thread by using the thread's Setdaemon (True) method.


Whether the daemon thread has completed the expected service task. Once all the user threads have exited, the virtual machine exits and runs.
Therefore, do not perform business logic operations (such as reading and writing data) in the daemon thread. 、




Setdaemon (TRUE) must be set before the start () method of the calling thread, or the illegalthreadstateexception exception will run out.
The new thread that is generated in the daemon thread is also the daemon thread.
Do not assume that all applications can be assigned to a daemon for service, such as read-write operations or computational logic.



3, the data that the thread operates

Synchronization issues:


4, can re-enter the internal lock
Each Java object can be used as a lock that implements synchronization, which is called a built-in lock or a monitor lock.
The thread acquires the lock automatically before it enters the synchronization code block, and the lock is automatically released when the synchronization code block exits.
The only way to get a built-in lock is to enter a synchronous code block or method protected by this lock.


A thread that holds a synchronization object lock can enter this synchronization code block or method multiple times. That is, the Sync object lock can be re-entered!
When the same thread calls the Synchronized method/block in the other synchronized method/block or parent class in this class, it does not prevent the thread from executing because the mutex can be reentrant.






6. Java Memory model
In the current Java memory model, threads can store variables in local memory (such as the machine's registers), rather than read and write directly in main storage. (Local RAM + shared main memory)


A volatile-modified member variable forces the value of the member variable to be reread from shared memory each time it is accessed by the thread. Also, when a member variable changes, forcing the thread to write the change back to the shared memory.
So at any moment, two different threads always see the same value for a member variable.
The volatile keyword is the hint JVM: for this member variable, you cannot save its private copy, but you should interact directly with the shared member variable.


Special rules for volatile variables:


1. Ensure the visibility of this variable to all threads. It is important to note that the write operation of the volatile variable is visible in addition to its own read operation, and all shared variables prior to the volatile write operation can be seen for operations after the volatile read operation
2. Prohibit Order reordering optimization
The final domain ensures the security of the initialization process, allowing unrestricted access to immutable objects and eliminating the need to synchronize the objects when they are shared


Therefore, it is not necessary to specifically declare long and double variables as volatile when coding.
Main memory vs. working memory


The Java memory model stipulates that all variables are stored in main memory, and each thread has its own working memory, and that the thread's working memory holds a copy of the main memory of the variable used by that thread.
All operations of a thread on a variable (reads, assigns, and so on) must be made in working memory, not directly read and written to variables in the main memory.




According to the Java Virtual Machine specification, the volatile variable still has a copy of the shared memory, but due to its special sequence of operations-before reading and writing data from working memory,
The data in main memory must be synchronized to the working memory, all of which look like read-write access directly in main memory, so the description here is no exception to volatile




A thread is not allowed to discard its most recent assign operation, that is, the variable must be synchronized back to main memory after it has changed in working memory.
If you perform a lock operation on a variable, the value of this variable in the working memory will be emptied, and the value of the variable initialized by the load or assign operation needs to be re-executed before the execution engine uses the variable.
Before performing a unlock operation on a variable, you must first synchronize this variable back to main memory (


7. Lightweight synchronization
Volatile is a slightly weaker synchronization mechanism that does not perform lock operations when accessing volatile variables, and does not perform thread blocking, so the Volatilei variable is a more lightweight synchronization mechanism than the Synchronized keyword.




Usage Recommendation: Use volatile on member variables that require access by two or more threads. Volatile is not necessary when the variable to be accessed is already in the synchronized code block, or is a constant.
It is inefficient to use volatile to mask the necessary code optimizations in the JVM, so use this keyword when necessary.




If there are two threads reading and writing volatile variables, thread A writes a volatile variable, and thread B reads the volatile variable, it can see that thread a writes to the volatile variable.
The key here is that it will not only see the write operation to the volatile variable, all the shared variables visible before the A thread writes the volatile variable, and the B thread will immediately become visible to the B thread after it reads the same volatile variable.




Happen-before Rules Introduction
This means that before the operation B, the effect of operation A can be observed by Operation B, "Impact" includes modifying the value of shared variables in memory, sending a message, calling a method, and so on, it is not much related to the occurrence of time.
Thread Start rule: the Start () method of the thread object Happen-before every action of this thread.






8. Synchronization Lock Description
When the thread has this lock tag, it can access the resource, and no lock tag will enter the lock pool. Any object system will create a mutex for it.
This lock is intended to be assigned to the thread, preventing an atomic operation from being interrupted. A lock on each object can be assigned to only one thread, so it is called a mutex.


If there are two or more threads in the same method, each thread has its own copy of the local variables.
Each instance of the class has its own object-level lock


Access to the synchronization code block in different instance objects of the same class, there is no blocking waiting to acquire the object lock problem,
Because they get the object-level locks of their respective instances, there is no effect on each other.


Holding an object-level lock does not prevent the thread from being swapped out, nor does it block other threads from accessing non-synchronized code in the same sample object.


A thread holding an object-level lock causes other threads to block out of all synchronized code.


Using the synchronized (OBJ) synchronization statement block, you can get an object-level lock on the specified object.




Class-level locks are shared by all samples of a particular class and are used to control concurrent access to static member variables and static methods. The specific usage is similar to the object level lock.






10. Secure use of the collection API in a multithreaded environment




Originally designed vectors and Hashtable are multithreaded safe.


There are several static methods in the collections class that can obtain a collection that is encapsulated by a synchronous method to encapsulate a non-synchronous collection:



public static list synchronizedlist (list L)


List List = Collection.synchronizedlist (new ArrayList ());
Note that the ArrayList instance is immediately encapsulated and there is no direct reference to the unsynchronized ArrayList (that is, to encapsulate the anonymous instance directly).
This is one of the safest ways. If another thread is to refer directly to the ArrayList instance, it can perform a non-synchronous modification.


From the perspective of memory visibility, writing a volatile variable is equivalent to exiting a synchronous code block, while reading a volatile variable is equivalent to entering a synchronous block of code.




, a volatile variable is a slightly weaker synchronization mechanism that does not perform a lock operation when accessing a volatile variable, so the execution thread is not blocked, so the volatile variable is a more lightweight synchronization mechanism than the Synchronized keyword.




Reason is a simple variable declared volatile if the current value is related to the previous value of the variable, then the volatile keyword does not work, meaning that the following expression is not an atomic operation: "count++", "Count = count+1".


You should use a volatile variable only if all of the following conditions are true:
1, the write operation to the variable does not depend on the current value of the variable, or you can ensure that only a single thread updates the value of the variable.
2. The variable is not included in the invariant with other variables.






Third, the deadlock problem
Follow these guidelines to help circumvent deadlocks:




1, only in the shortest time necessary to hold the lock, consider the use of synchronous statement block instead of the entire synchronization method;
2. Try to write code that does not need to hold multiple locks at the same time, and if unavoidable, make sure the thread holds the second lock for as short a time as possible;
3, create and use a large lock to replace a number of small locks, and the lock for mutual exclusion, rather than as an object-level lock for a single object;


Four, thread communication




Before calling Wait (), the thread must obtain an object-level lock on the object, that is, the wait () method can only be called in a synchronous method or in a synchronous block. After entering the wait () method, the current thread releases the lock.
Notify () This method is also called in a synchronous method or synchronous block, that is, before the call, the thread must also obtain an object-level lock on the object, and if the call to notify () does not hold the appropriate lock, the illegalmonitorstateexception is thrown.


After notify, the current thread does not immediately release the object lock, and wait for the thread does not immediately get the object lock, wait until the program exits the synchronized code block, the current thread will release the lock, wait on the thread to get the object lock),
But do not disturb other threads that are also waiting to be notify by the object. When the first wait thread that obtains the object lock finishes running, it frees the object lock, and if the object does not use the Notify statement again, even if the object is idle,
Other wait-state waiting threads continue to block in the wait state until the object emits a notify or notifyall because they are not notified of the object. Note here: They wait for the notify or notifyall, not the lock.


This is not the case when the following Notifyall () method is executed.




Notifyall all the threads that originally waited on the object to exit the wait state (that is, all wakes up, no longer waits for notify or notifyall, but because the object lock has not been acquired at this time, and therefore cannot continue down),
becomes waiting to get the lock on the object, and once the object lock is freed (the notifyall thread exits the call to Notifyall's synchronized code block), they compete.
If one of the threads acquires the object lock, it will continue to execute, and after it exits the synchronized code block, releasing the lock, the other threads that have been awakened will continue to compete to acquire the lock, continuing until all the awakened threads have executed.






If the thread calls the object's Wait () method, the thread is in the object's wait pool, waiting for the thread in the pool to not compete for the lock on the object.
When a thread calls the object's Notifyall () method (Wake all wait threads) or the Notify () method (which only randomly wakes up a wait thread), the awakened threads go into the object's lock pool, and the thread in the lock pool competes for that object lock.
A high-priority thread competes for the probability of an object lock, and if a thread does not compete with the object lock, it will remain in the lock pool, and the Wait () method will be called again by the wired thread to return to the waiting pool. And the thread that competes to the object lock continues to execute,
Until the synchronized code block is executed, it frees the object lock, and the thread in the lock pool continues to compete for that object lock.








Summary: When using the thread's wait/notification mechanism, it is generally necessary to match a Boolean value (or any other condition that can determine the true or false), change the value of the Boolean variable before notify, and let wait return to exit while loop
(Typically, a while loop is added to the perimeter of the wait method to prevent early notification), or after the notification is omitted, it is not blocked at the wait method. This guarantees the correctness of the program.






V. New features of concurrency
1.
In general, Cachedtheadpool typically creates the same number of threads as required during program execution, and then stops creating a new thread when it reclaims the old thread.
So it is the preferred choice for a reasonable executor, and only if this approach can cause problems (such as the need for a large number of long-time connection-oriented threads), you need to consider using Fixedthreadpool.




Service-oriented connection: public static executorservice newfixedthreadpool (int nthreads)




Executor performing runnable tasks
Executor Performing callable Tasks




After Java 5, the tasks are divided into two categories: one is the class that implements the Runnable interface, and the other is the class that implements the callable interface. Both can be executed by Executorservice,
However, the runnable task does not return a value, and the callable task has a return value. and callable's call () method can only be executed by Executorservice's submit (callable<t> Task) method,
and returns a <t>future<t&gt that represents the future of the task waiting to be completed.




The callable interface is similar to runnable, and both are designed for classes whose instances might be executed by another thread. However, Runnable does not return results, and cannot throw a checked exception callable and return the result.
And an exception may be thrown when the returned result is obtained. The call () method in callable is similar to the runnable run () method, and the difference is the same as the return value, which does not.




When a callable object is passed to the Executorservice's Submit method, the call method executes automatically on a thread and returns the execution result to the future object. Similarly, the Runnable object is passed to the Executorservice's Submit method,
The Run method executes automatically on a thread and returns the execution result of the future object, but calls the Get method on the future object, which returns NULL.


2. Custom thread pool


Threadpoolexecutor class creation, which has multiple construction methods to create a thread pool


Blockingqueue<runnable>




Concurrency new features-lock locks and condition variables





Java Multi-threading, concurrent programming Knowledge Point Summary

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.