One, thread safety
When multiple threads execute the same piece of code, each execution result is the same as the result of single-threaded execution, and there is no two semantics for the execution result, which can be called thread-safe.
When it comes to thread safety, it means that access to shared resources in a multithreaded environment can cause inconsistencies in this shared resource. Therefore, to avoid thread-safety issues, you should avoid concurrent access to this shared resource in a multithreaded environment.
Thread safety issues are mostly caused by global variables and static variables, which are generally thread-safe when multiple threads are performing only read operations on shared data, and when more than one thread is performing a write operation, you need to consider thread synchronization to address thread safety issues.
second, thread Synchronization (Synchronized/lock)
thread synchronization: the line of code that operates the shared data as a whole, allowing only one thread to execute at the same time, and other threads in the process not participating in execution. The goal is to prevent data corruption when multiple threads access a data object.
(1) Synchronization method (synchronized)
The method definition that accesses a shared resource is added with the Synchronized keyword adornment, making this method known as a synchronous method. This method can be simply understood to be locked, and its lock object is the object itself where the current method resides. In a multithreaded environment, when this method is executed, the synchronization lock is first acquired (and at most one thread is available at the same time), and the lock object is released only when the thread finishes executing the synchronization method, and the other threads are likely to get the synchronization lock, and so on ... The format is as follows:
Public synchronized void run () { // ...}
(2) Synchronous code block (synchronized)
When using the synchronous method, the whole method body becomes the synchronous execution state, which makes it possible for the synchronization scope to be too large, so that the code that needs synchronization can be solved by synchronizing the code block directly with another synchronization mode. The format is as follows:
synchronized (obj) { // ...}
Where obj is the lock object, it is important to choose which object to use as a lock. In general, this shared resource object is selected as the lock object.
(3) Sync Lock (Lock)
The lock object synchronization lock makes it easy to solve the problem of selecting a lock object, and the only thing you need to be aware of is that the lock object needs to have a one-to-ones relationship with the resource object. Lock Object Sync Lock the general format is:
class X { // display defines the lock synchronization lock object, which has a one-to-one relationship with the shared resource privatefinalNew Reentrantlock (); Public void m () { // locking lock.lock (); // ... Code required for thread-safe synchronization // release lock lock lock.unlock (); }}
When to sync:
(1) Visibility synchronization : Must be synchronized in the following cases: 1) Read the last variable that might have been written by another thread, 2) write the next variable that might be read by another thread
(2) Consistency synchronization : When you modify multiple related values, you want the other threads to see this set of changes atomically-either see all the changes or see nothing.
This applies to related data items, such as the location and rate of particles, and metadata items such as the data values contained in the linked list and the chain of data items in the lists themselves.
In some cases, you do not have to use synchronization to pass data from one thread to another because the JVM has implicitly performed synchronization for you. These situations include:
- Initialized by a static initializer (on a static field or in a static{} block)
- When initializing data
- When you access the final field
- When an object is created before the thread is created
- When a thread can see the object it will be working on
The principle of Lock:
- Each object in Java has a built-in lock
- When the program runs to a non-static synchronized synchronization method, the lock associated with the current instance (this instance) of the executing code class is automatically obtained. Acquiring a lock on an object is also known as acquiring a lock, locking an object, locking on an object, or synchronizing on an object.
- The object lock does not work until the program runs to the synchronized synchronization method or code block.
- An object has only one lock. Therefore, if a thread obtains the lock, no other thread can get the lock until the first thread releases (or returns) the lock. This also means that no other thread can enter the synchronized method or block of code on the object until the lock is freed.
- A release lock is a lock thread that exits the synchronized synchronization method or code block.
key to lock and sync:1), can only synchronize the method, and cannot synchronize variables and classes, 2), each object has only one lock; when it comes to synchronization, what should be clearly synchronized? In other words, on which object is it synchronized? 3), you do not have to synchronize all the methods in the class, the class can have both synchronous and non-synchronous methods. 4), if two threads are going to execute the synchronized method in a class, and two threads use the same instance to invoke the method, only one thread can execute the method at a time, and the other waits until the lock is freed. That is, if a thread obtains a lock on the object, no other thread can enter any one of the synchronization methods in the class (the object). 5), if the thread has synchronous and non-synchronous methods, the non-synchronous method can be freely accessed by multiple threads without being restricted by the lock. 6), when the thread sleeps, any locks it holds will not be released. 7), threads can obtain multiple locks. For example, a synchronous method that invokes another object in a synchronous method of an object acquires a synchronization lock for two objects. 8), synchronization damage concurrency, should be as narrow as possible synchronization range. Synchronization can not only synchronize the entire method, but also synchronize some of the code blocks in the method. 9), when using synchronous code blocks, you should specify which object to synchronize on, that is, which object to get the lock. 10), synchronous static method, need a lock for the whole class object, this object is this class (Xxx.class).
What happens if a thread doesn't get a lock:If a thread attempts to enter the synchronization method and its lock is already occupied, the thread is blocked on the object. Essentially, a thread enters a pool of that object, where it must wait until its lock is freed and the thread becomes operational or running again.
Thread Deadlock:When two threads are blocked, a deadlock occurs when each thread waits for another thread. There are some design methods that can help avoid deadlocks, such as the policy of always acquiring locks in a predefined order.
Thread Synchronization Summary1, the purpose of thread synchronization is to protect multiple threads to ask a resource when the destruction of resources. 2, thread synchronization method is through
LockTo implement, each object has and has only one lock, which is associated with a particular object, and once the thread acquires the object lock, other threads that access the object can no longer access other synchronization methods for that object. 3, for the static synchronization method, the lock is for this class, the lock object is the class object. Static and non-static methods of locking do not interfere. A thread acquires the lock, which is obtained when a synchronization method on another object is accessed in a synchronous method. 4, for synchronization, to be awake at all times on which object synchronization, this is the key. 5, write thread-safe classes, you need to pay attention to multiple threads competing access to the logic and security of the resources to make the right judgment, the "atomic" operation to make an analysis, and ensure that other threads during atomic operation can not access the competing resources. 6. When multiple threads wait for an object lock, the thread that does not acquire the lock will block. 7, deadlock is between the threads waiting for lock-lock caused by, in practice, the probability of occurring is very small. Really let you write a deadlock program, not necessarily good, hehe. However, once the program has a deadlock, the program will die.
third, thread communication:Wait ()/notify ()/notifyall ()
Wait (): causes the current thread to wait and put it into a wait-blocking state. This thread is awakened until other threads call the Notify () or Notifyall () method of the synchronization lock object.
- void wait (long timeout)-Causes the current thread to wait until another thread calls the Notify () method of this object or the Notifyall () method, or exceeds the specified amount of time.
- void Wait (long timeout, int Nanos)-Causes the current thread to wait until another thread calls this object's notify () method or Notifyall () method, or some other thread interrupts the current thread, or has exceeded an actual amount of time.
notify (): wakes a single thread waiting on this synchronization lock object, and if more than one thread waits on this synchronization lock object, any one of the threads will be selected for wake-up operation, and the thread that wakes up may be executed only if the thread discards the lock on the synchronization lock object.
Notifyall (): Wakes all threads waiting on this sync lock object, and only the thread that wakes up can be executed if the front thread discards the lock on the synchronization lock object.
These three methods are mostly used in multi-threading, but are actually local methods in the object class. Therefore, in theory, any object objects can be the keynote of these three methods, in the actual multithreaded programming, only the synchronous lock object tune these three methods, to complete the thread communication between multithreading.
Note the point:
After the 1.wait () method executes, the current thread immediately enters the wait-blocking state, after which the code does not execute;
The 2.notify ()/notifyall () method wakes up (any one of the-notify ()/All-notifyall ()) thread objects on this synchronization lock object, but at this point the synchronization lock object is not released, that is, if the Notify ()/ Notifyall () is followed by code that will continue, knowing that the current thread has finished executing before releasing the synchronization lock object;
3.notify ()/notifyall () after execution, if the right side of the sleep () method, it will cause the current thread into the blocking state, but the synchronization object lock is not released, and still keep, then after a certain time will continue to execute this thread, followed by 2;
4.wait ()/notify ()/nitifyall () the completion of communication or collaboration between threads is based on different object locks, so if a different synchronization object lock will lose meaning, at the same time, the synchronization object lock is best to maintain a one by one correspondence with the shared resource object;
5. When the wait thread wakes up and executes, it continues after the wait () method code that was last executed.
Iv. questions related to the relevant side
1. What is the difference between threads and processes?
A: A process is a standalone (self contained) operating environment that can be viewed as a program or an application. A thread is a task that executes in a process. A thread is a subset of processes, a process can have many threads, and each thread performs different tasks in parallel. Different processes use different memory spaces, and all threads share the same amount of memory space. Don't confuse it with stack memory, each thread has a separate stack of memory to store local data.
2. How do I implement threads in Java? Compare this kind of way
A: There are two ways of creating a thread:
(1) Inherit the thread class and extend the threads.
(2) Implement Runnable interface.
The way to inherit the thread class has its inherent disadvantage, because Java inherits the uniqueness, inherits the thread class can not inherit other classes, also does not conform to the inheritance semantics, the dog and the thread does not have the direct parent-child relationship, inherits the thread only to have some function characteristic.
The implementation of the Runnable interface, ① avoid the limitations of single inheritance, ② at the same time more in line with object-oriented programming, the thread object is a separate package, ③ and implementation of the interface to reduce the threading object (DOG) and the threading task (the code in the Run method), ④ as described above, You can use an instance of the same dog class to create and open multiple threads, making it easy to share resources. In fact, the thread class also implements the Runnable interface. The actual development of many is the use of the implementation of the Runnable interface method.
3. Does starting a thread call the run () or start () method?
A: Starting a thread is calling the start () method so that the virtual processor represented by the thread is in a running state, which means it can be dispatched and executed by the JVM, which does not mean that the thread will run immediately. The run () method is the method by which a callback (callback) is to be made after the thread starts.
4. Wai () T and sleep () comparison
Common:
1). They are all in a multi-threaded environment, thesleep () method and the Wait () method of the object allow the thread to pause execution , and can block the specified number of milliseconds at the call of the program and return.
2). Wait () and sleep () can break the thread's suspend state through the interrupt () method, causing the thread to throw interruptedexception immediately.
If thread A wants to end thread B immediately, you can call the interrupt method on the thread instance that corresponds to threads B. If thread B is wait/sleep/join at the moment, thread B will immediately throw interruptedexception, and return directly in catch () {} to safely end the thread. It is important to note that Interruptedexception is thrown from within the thread itself, not by the interrupt () method. When you call interrupt () on a thread, the thread does not throw interruptedexception at all if it is executing normal code. However, once the thread has entered wait ()/sleep ()/join (), the interruptedexception is immediately thrown.
Different points:
1). Method of the thread class : Sleep (), yield (), etc.
Methods of the object class : Wait () and notify (), etc.
2). Each object has a lock to control synchronization access. The Synchronized keyword can interact with the object's lock to achieve thread synchronization.
The Sleep () method causes the current thread to pause execution for a specified time, giving the execution opportunity (CPU) to another thread, but the lock on the object remains, and the thread automatically returns to the ready state after the sleep has ended;
The wait () method causes the current thread to discard the lock on the object (the thread pauses execution), into the object's wait pool (wait pools), only the Notify () method of the calling object (or the Notifyall () method) to wake the thread in the waiting pool into the lock pool (lock Pool), if the thread re-obtains the lock on the object, it can go into a ready state.
3). Wait,notify and Notifyall can only be used in a synchronous control method or in a sync control block , and sleep can be used anywhere
4). Sleep must catch exceptions, while wait,notify and notifyall do not need to catch exceptions
So the biggest difference between the sleep () and wait () methods is:
Sleep () when sleeping, keep the object lock, still occupy the lock;
While wait () sleeps, the object lock is released.
But wait () and sleep () can break the thread's suspend state through the interrupt () method, causing the thread to throw interruptedexception immediately (but not recommended).
5. What is the difference between the sleep () method and the yield () method?
The ①sleep () method gives other threads the opportunity to run without taking into account the priority of the thread, thus giving the low-priority thread a chance to run, and the yield () method only gives the same priority or higher priority to the thread that runs the opportunity;
The ② thread executes the sleep () method and then goes into a blocking (blocked) state, and the yield () method is transferred to the ready State;
The ③sleep () method needs to declare the throw interruptedexception, and the yield () method does not declare any exceptions;
The ④sleep () method is more portable than the yield () method, which is related to operating system CPU scheduling.
6. Some common methods of threading classes:
- Sleep (): Forcing a thread to sleep n milliseconds is a static method that calls this method to handle the interruptedexception exception;
- Join (): Allow one thread to wait for another thread to finish before continuing execution;
- Yeild (): Thread concession, pausing the currently executing thread object to yield CPU resources, transitioning the current thread from the running state to the ready state and executing other threads with the same or higher precedence;
- IsAlive (): Determines whether a thread is alive.
- Activecount (): The number of active threads in the program.
- Enumerate (): Enumerates the threads in the program.
- CurrentThread (): Gets the current thread.
- Isdaemon (): Whether a thread is a daemon thread.
- Setdaemon (): Sets a thread as the daemon thread. (The difference between a user thread and a daemon thread is whether to wait for the main thread to end up relying on the main thread end)
- SetName (): Sets a name for the thread.
- SetPriority (): Sets the priority of a thread.
- Wait (): causes a thread to be in the waiting (blocking) state and releases the lock on the object it holds;
- Notify (): Wakes up a waiting thread, of course, when calling this method, does not actually wake up a waiting state of the thread, but by the JVM determines which thread to wake, and is not related to the priority level;
- Notityall (): Wakes up all waiting threads, the method is not to lock the object to all threads, but to let them compete, only the thread that obtains the lock can enter the ready state;
7. Differences between synchronous code blocks and synchronization methods
The difference between the two is mainly reflected in the synchronization lock above. For the synchronous method of the instance, because only this is used as a synchronous lock, if more than one lock is required in a class, in order to avoid the conflict of the lock, it is necessary to use different objects, when the synchronization method does not satisfy the requirement, only the synchronous code block can be used to pass in any object. , or multiple classes need to use the same lock, this time the instance of multiple classes this is obviously different, you can only use the synchronous code block, passed to the same object.
8. Compare synchronized and lock
1), synchronized is the key word, and if...else ... , it is a syntax-level implementation, so synchronized acquisition and release locks are all Java virtual machines help the user to complete, Reentrantlock is a class-level implementation, so lock acquisition and the release of locks require the user to operate on their own. especially remind again, Reentrantlock in Lock () is finished, must be manual unlock (), usually put in finally statement block.
2), synchronized simple, simple means not flexible, and reentrantlock lock mechanism to the user's use provides a great deal of flexibility. This is vividly reflected in Hashtable and Concurrenthashmap. Synchronized locks the entire hash table, while Concurrenthashmap uses Reentrantlock to achieve the lock separation , the lock is only segment rather than the entire hash table
3), synchronized is not fair lock, and Reentrantlock can specify whether the lock is fair or not fair
4), synchronized implementation of the waiting/notification mechanism notification thread is random, reentrantlock implementation wait/notification mechanism can selectively notify
5), compared with synchronized, Reentrantlock provides users with various methods for obtaining lock information, such as knowing whether lock is fetched by the current thread, how many times lock is called by the same thread, whether lock is fetched by any thread, etc.
To sum up, I think if you only need to lock simple methods, simple code blocks, then consider using synchronized, complex multithreaded processing scenarios can consider using Reentrantlock.
Reference Links:
Http://www.importnew.com/21136.html
http://lavasoft.blog.51cto.com/62575/99155/
Http://www.cnblogs.com/lwbqqyumidi/p/3821389.html
Java Multithreading (ii)-thread-safe, thread-synchronous, inter-thread communication (with polygon test sets)