Java Advanced Technology Chapter 5 - Several Issues from the Synchronized Keyword to Transaction Concurrency in High Concurrency Programming

foreword

Foreword click here:
http://blog.csdn.net/wang7807564/article/details/79113195

synchronized keyword

Visibility and atomicity are guaranteed through the use of this keyword.
Synchronized locks an object instead of a variable. Since each synchronized code area is guaranteed to be occupied by only one thread, this kind of lock also becomes a mutex lock. This specific locked object can be a specific object after instantiation, or it can be this, or an object of class type.

for:

synchronized(this){代码区}

This way of writing, you can use synchronized as a keyword in the function definition, for example:

public synchronized void m(){代码区}

For, when synchronized is used as a keyword to modify a static method, for example:

public synchronized static void m(){代码区}

Equivalent to:

synchronized(包名.类名.class)

In the same object, synchronized and unsynchronized methods can run at the same time. The so-called synchronized method refers to the method modified with the synchronized keyword.

The pitfalls of synchronized

Synchronized is a keyword in java, that is to say, it is a built-in feature of the Java language.
If a code block is modified by synchronized, when a thread acquires the corresponding lock and executes the code block, other threads can only wait until the thread acquiring the lock releases the lock, and the thread acquiring the lock here releases the lock only There will be two situations:

  1. The thread that acquired the lock finishes executing the code block, and then the thread releases its possession of the lock;
  2. When an exception occurs in thread execution, the JVM will automatically release the lock from the thread.

Transaction concurrency issues

Dirty read problem (dirty read)

Dirty read refers to when a transaction is accessing data and making changes to the data, and this modification has not been committed to the database, at the same time, another transaction also accesses the data, and then uses the data.
Because this data is uncommitted data, the data read by another transaction is dirty data.
It can be considered that the problem is due to the fact that the business write method is locked, but the business read method is not locked, and the atomicity is not guaranteed when writing data, resulting in inconsistent data.
You can add an exclusive lock when modifying, and release it after the transaction is committed, and add a shared lock when reading to solve this problem.

unrepeatable read

Non-repeatable read means that in the same transaction, the same data is read twice, and the content is different.
The main reason for the difference between the two reads of the same transaction is that the atomicity of the two reads of the transaction is not guaranteed, causing the middle of the two reads to be rewritten by another transaction, resulting in the second read. The result of a transaction overwrite.
Two reads can be combined into one operation, and write locks are added before and after the two reads to ensure that the data is not modified.

phantom problem

Phantom reading is similar to non-repeatable reading, except that the result obtained by phantom reading is not the result of the queried data, but the number of records obtained after traversal.
That is, in the same transaction, the same operation is used to read twice, and the number of records obtained is not the same.
The pattern diagram is as follows:

        事务1:查询表中所有记录
                          -------------->事务2:插入一条记录
                          -------------->事务2:调用commit进行提交
        事务1:再次查询表中所有记录

transaction isolation

Many of the above situations occur in the database system. The database system faces the problems caused by concurrent reading and writing. For this reason, the database system often has a transaction isolation mechanism. The solution is:
five levels of transaction isolation:

  1. TRANSACTION_NONE Do not use transactions.
  2. TRANSACTION_READ_UNCOMMITTED Dirty reads are allowed.
  3. TRANSACTION_READ_COMMITTED prevents dirty reads, the most commonly used isolation level, and is the default isolation level for most databases
  4. TRANSACTION_REPEATABLE_READ prevents dirty reads and non-repeatable reads,
  5. TRANSACTION_SERIALIZABLE can prevent dirty reads, non-repeatable reads and phantom reads, (transaction serialization) will reduce the efficiency of the database

Express in a table:

category dirty read non-repeatable read hallucinations
Read uncommitted
Read committed ×
Repeatable read × ×
Serializable × × ×

Note: × means it will not happen, √ means it may happen

Reentrant lock:

Reentrant locks are also reentrant locks, also known as recursive locks, which means that after the outer function of the same thread acquires the lock, the inner recursive function still has the code to acquire the lock, but it is not affected.
A thread already owns the lock of an object, and it will still get the lock of the object when it applies again, that is to say, the lock obtained by synchronized is reentrant. Similarly, subclasses can also call synchronized methods of the superclass. The locks implemented by the lock interface contacted later are also reentrant.
That is to say, both ReentrantLock and synchronized are reentrant locks in the JAVA environment.
However, if an object has two methods, both of which are decorated with synchronized, then when the two methods of the same object are executed in two threads, it is necessary to wait. E.g:

LockObj r= new LockObj();
new Thread(()->r.m1()).start();
new Thread(()->r.m2()).start();

These two methods m1 and m2 are both modified with synchronized, then use the same object synchronized(this), which requires a sequence to obtain the lock.

Synchronized exception handling:

During the execution of the program, if an exception occurs, the lock will be released by default. Therefore, in the process of concurrent processing, if there is an exception, be careful, otherwise inconsistency may occur. If you do not want to release the lock, pay attention to using catch to handle this exception.

synchronized optimization:

The fewer statements in the synchronization code block, the better. You can use synchronized(this){code block}. Try not to use synchronized as a keyword to modify the entire method area. Using fine-grained locks can shorten the thread contention time. thereby increasing efficiency. E.g:

synchronized(this) {
        count ++;
}

It is much stronger than the coarse-grained coding method that defines the synchronized keyword in front of the method.

Lock object:

Lock an object o, if the properties of o change, the use of the lock will not be affected. But if o becomes another object, that is, the reference to the variable o changes, the locked object changes. Turning references to locked objects into other objects should be avoided.
A lock is a locked object in heap memory, not a reference to an object in stack memory.
In JAVA, string constants can also be used as lock objects, but do not use string constants as lock objects, because your program and the class library you use are likely to use the same lock inadvertently, causing very strange Deadlock blocking.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324601504&siteId=291194637