Code examples of seven ways of thread synchronization in Java multithreading
Why use synchronization?
Java allows multithreading concurrency control. When multiple threads operate a shareable resource variable at the same time (such as data addition, deletion, modification and query), the data will be inaccurate and conflict with each other. Therefore, a synchronization lock is added to avoid being called by other threads before the thread completes the operation, so as to ensure the uniqueness and accuracy of the variable.
1. Synchronization method
That is, the method modified by the synchronized keyword. Since each object in Java has a built-in lock, when a method is modified with this keyword, the built-in lock will protect the whole method. Before calling this method, you need to obtain the built-in lock, otherwise it will be blocked. Code such as: public synchronized void save() {}
Note: the synchronized keyword can also modify a static method. At this time, if the static method is called, the whole class will be locked
2. Synchronization code block
That is, a statement block decorated with the synchronized keyword. The statement block modified by this keyword will be automatically added with a built-in lock to synchronize the code, such as synchronized (object) {}
Note: synchronization is a high overhead operation, so the content of synchronization should be minimized.
Generally, it is not necessary to synchronize the whole method. You can use the synchronized code block to synchronize the key code.
Code example:
3. Use special domain variable (volatile) to realize thread synchronization
a. Volatile keyword provides a lock free mechanism for accessing domain variables. B. using volatile to modify a domain is equivalent to telling the virtual machine that the domain may be updated by other threads. C. Therefore, each time the domain is used, it needs to be recalculated instead of using the value in the register. D. volatile does not provide any atomic operations, and it cannot be used to modify variables of final type
For example:
In the above example, just add volatile modification in front of account to realize thread synchronization.
Code example:
Note: the asynchronous problem in multithreading mainly occurs in the reading and writing of the domain. If the domain itself avoids this problem, there is no need to modify the method of operating the domain.
Using final domain, lock protected domain and volatile domain can avoid the problem of asynchrony.
4. Use reentry lock to realize thread synchronization
In Java se 5 0 added a Java util. Concurrent package to support synchronization. The reentrantlock class is a lock that is reentrant, mutually exclusive and implements the lock interface. It has the same basic behavior and semantics as using the synchronized method and fast, and extends its capabilities. The common methods of the reentrantlock class are: reentrantlock (): create a reentrantlock instance lock (): obtain the lock unlock (): release the lock
Note: reentrantlock () also has a construction method that can create a fair lock, but it is not recommended because it can greatly reduce the running efficiency of the program
For example:
Based on the above example, the rewritten code is:
Code example:
Note: selection of lock object and synchronized keyword:
a. You'd better not use either and use a Java util. The concurrent package provides a mechanism to help users deal with all lock related code. b. If the synchronized keyword can meet the needs of users, use synchronized because it can simplify the code. C. if more advanced functions are required, use the reentrantlock class. At this time, pay attention to releasing the lock in time, otherwise deadlock will occur. Usually, release the lock in the finally code
5. Thread synchronization using local variables
If ThreadLocal is used to manage variables, each thread using the variable will get a copy of the variable, which are independent of each other, so that each thread can modify its own copy of the variable at will without affecting other threads.
Common methods of ThreadLocal class threadlocal(): create a thread local variable get(): return the value in the current thread copy of the thread local variable initialvalue(): return the "initial value" set (t value) of the current thread of the thread local variable: set the value in the current thread copy of the thread local variable to value
For example:
Based on the above example, the modified code is:
Code example:
Note: ThreadLocal and synchronization mechanism
a. Both ThreadLocal and synchronization mechanisms are designed to solve the access conflict of the same variable in multiple threads. b. The former adopts the method of "space for time", while the latter adopts the method of "time for space"
6. Thread synchronization using blocking queue
The first five synchronization methods are thread synchronization implemented at the bottom, but we should stay away from the bottom structure as far as possible in actual development. Use javase5 New Java. Net in version 0 util. The concurrent package will help simplify development. This section mainly uses linkedblockingqueue < E > to synchronize threads. Linkedblockingqueue < E > is a blocking queue with arbitrary range based on connected nodes. Queues are first in first out (FIFO), which will be explained in detail later~
Linkedblockingqueue class common methods
Linkedblockingqueue(): create an integer MAX_ Value's linkedblockingqueue put (E): add an element at the end of the queue. If the queue is full, block it. Size(): return the number of elements in the queue. Take(): remove and return the queue head element. If the queue is empty, block it
Code example:
Realize the synchronization of merchants' production and sale of goods
Note: BlockingQueue < E > defines the common methods of blocking queues, especially the three methods of adding elements. We should pay more attention to when the queue is full:
The add () method throws an exception, the offer () method returns false, and the put () method blocks
7. Thread synchronization using atomic variables
The fundamental reason for using thread synchronization is that the operation on ordinary variables is not atomic.
So what is atomic operation? Atomic operation refers to the operation of reading variable value, modifying variable value and saving variable value as a whole, that is - these behaviors are either completed at the same time or not.
In Java util concurrent. The atomic package provides a tool class for creating atomic type variables, which can be used to simplify thread synchronization. The atomicinteger table can update the value of int atomically, which can be used in applications (such as counters incremented atomically), but cannot be used to replace integer; Extensible number, which allows unified access to tools and utilities dealing with opportunity digital classes.
Common methods of atomicinteger class:
Atomicinteger (int initialvalue): create a new atomicinteger addget (int dalta) with a given initial value: add the given value to the current value atomically get(): get the current value
Code example:
Only change the bank class, and the rest of the code is the same as the first example above
Supplement - atomic operations mainly include:
Read and write operations for reference variables and most original variables (except long and double); Read and write operations for all variables decorated with volatile, including long and double.
In the world of code, you are God.
summary
The above is all about the code examples of seven ways of thread synchronization in Java multithreading. I hope it will be helpful to you. Interested friends can continue to refer to this site: Java Multithread hunger and fairness introduction and code examples, Java programming multithread deadlock and simple implementation code of inter thread communication, Java Multithread blocking and wake-up code examples, etc. if you have any questions, you can leave a message at any time, and the editor will reply to you in time. Thank you for your support!