Reasons for safety problems in multithreading:
When multiple statements are operating on the same thread to share data, one thread only executes part of multiple statements, but not yet
After execution, another thread participates in the execution. The error that caused the shared data.
resolvent:
For statements with multiple operations sharing data, only one thread can complete the execution. During the execution, other threads cannot
Participate in the implementation.
Java provides a special solution to the security problem of multithreading: synchronization mechanism.
Method 1: synchronize code blocks
synchronized{
/ / code to be synchronized
}
explain:
1. The code that operates the shared data is the code that needs to be synchronized (be careful not to include more or less);
2. Shared data: variables operated by multiple threads;
3. Synchronization monitor: commonly known as lock, the object of any class can act as a lock (it is required that each thread must share a lock);
4. In the way of implementing the Runnab interface to create multithreading, you can consider using this as the synchronization monitor and inheriting the Thread class
In the way of creating multithreading, you can consider classes class as the synchronization monitor.
The following is a simple question about selling tickets in multiple windows
class Window implements Runnable{//Implement the Runnable method to create multithreading
private static int ticket = 100;//Number of votes
@Override
public void run() {//Override run method
while (true){
synchronized (this) {//Package the code that operates on shared data with synchronized
if (ticket > 0) {
//The name of the current thread
System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
At this time, for statements that operate on shared data, only when one thread finishes executing and releases the lock can other threads enter.
Method 2: use synchronization method
When the code that operates on shared data is completely declared in a method, this method can be set to synchronous.
be careful:
1. The synchronization method still involves the synchronization monitor, but we don't need to display the declaration;
2. Non static synchronization method. The synchronization monitor is this
Static synchronization method. The synchronization monitor is the current class itself (class. Class)
This is a non static synchronization method
//Implement Runnable interface to create multithreading
class Window1 implements Runnable{
private static int ticket = 100;//Number of votes
@Override
public void run() {//Override run method
while (true){
show();//This method is a method of operating shared data
}
}
private synchronized void show(){//Sync monitor is this
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);
ticket--;
}
}
}
This is a static synchronization method
//Inherit the Thread class to create a multithread
class Window2 extends Thread {
private static int ticket = 100;//Number of votes
@Override
public void run() {
while (true){
show();//This method is a method of operating shared data
}
}
private static synchronized void show(){//The synchronization monitor is window2 class
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":Ticket No.:" + ticket);
ticket--;
}
}
}
Mode 3: lock
class A{
private final ReentrantLock lock = new ReenTrantLock();
public void m(){
lock.lock();
try{
//
Thread safe code
;
}
finally{
lock.unlock();
}
}
}
explain:
1. From
JDK 5.0
Start,
Java
Provides a more powerful thread synchronization mechanism
-
The synchronization is realized by explicitly defining the synchronization lock object
Step. Sync Lock use Lock
Object acts as;
2,
java.util.concurrent.locks.Lock
Interface is used to control multiple threads to access shared resources
Tools. Locks provide common
For exclusive access to shared resources, only one thread can Lock the Lock object at a time. The thread should obtain the Lock before accessing the shared resources
Lock object;
3. The ReentrantLock class implements Lock, which has the same concurrency and memory semantics as synchronized
ReentrantLock is commonly used in process safety control, which can explicitly add and release locks.
class Windowlock implements Runnable{
private int trick = 100;
// Instantiate ReentrantLock
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
try {
//Call lock method
lock.lock();
if(trick > 0){
System.out.println(Thread.currentThread().getName() + ":" + trick);
trick--;
}else{
break;
}
} finally {
//Unlock
lock.unlock();
}
}
}
}
Comparison between synchronized and lock:
1. Lock is an explicit lock (manually open and close the lock, don't forget to close the lock),
synchronized
It's an implicit lock. It's out of scope automatically
Release;
2. Lock has only code block lock,
synchronized
There are code block locks and method locks;
3. Use Lock
Lock,
JVM
It will take less time to schedule threads for better performance. And it has better scalability (providing more
Multiple subclasses)
Priority:
lock - > synchronization code block - > synchronization method