thread safety

thread safety

The core of writing thread-safe code is to manage state access operations, especially access to shared and mutable state.

In an informal sense, an object's state refers to data stored in state variables (such as instances or static fields), and an object's state may contain other object-dependent fields.

Whether an object needs to be thread-safe depends on whether it will be accessed by multiple threads. To make an object thread-safe, a synchronization mechanism is required to coordinate access to the object's mutable state.

Java synchronization mechanism: keyword synchronized, volatile type variable, explicit lock (Lock), atomic variable.

Stateless objects must be thread-safe.

atomicity

Race Condition : A race condition occurs when the correctness of a computation depends on the timing of alternate execution of multiple threads. Examples are "read-modify-write" operations and "check-before-execute" operations.

  • "Read-modify-write" operation: The most classic is the auto-increment operation. For example, the count++ operation, which is non-atomic, actually consists of three operations: reading the value of count, adding one to the value, and writing the calculated result to count. If multiple threads access count and ++ at this time, the final result cannot be guaranteed to be correct.
  • "Check first, then execute" operation: The classic example is the singleton pattern .

Compound operations : To avoid race conditions, ensure that when a thread modifies a variable, it prevents other threads from using the variable in some way. The "read-modify-write" and "check-before-execute" operations are collectively referred to as compound operations: they contain a set of operations that must be performed atomically to ensure thread safety.

The locking mechanism is a built-in mechanism in Java to ensure atomicity.

locking mechanism

Built-in lock:

Synchronized block (Synchronized Block). Built-in locks can support atomicity and visibility. A synchronized code block consists of two parts:

  • an object reference as a lock;
  • a block of code protected by this lock;

The lock of the synchronized code block is the object where the method call is located. The static synchronized method uses the class object as the lock.

Java's built-in lock is equivalent to a type of mutex (or mutex), which means that at most one thread can hold such a lock.

Reentrant:

When a thread requests a lock held by another thread, it blocks. Because built-in locks are reentrant, if a thread tries to acquire a lock that it already owns, it will succeed. "Reentrancy" means that the granularity of the operation to acquire the lock is "thread", not "call".

One way to implement reentrancy is to set a counter for each lock, the same thread acquires the lock again, the counter is incremented by one, and when the thread exits the synchronized code block, the counter is decremented by one.

If the built-in lock is not reentrant, the following code will deadlock:

public class Widget{
    public synchronized void doSomeThing(){ ... }
}

public class LoggingWidget extends Widget{
    public synchronized void doSomeThing(){
        //如果是非重入的锁,获取Widget上的锁时就会发生死锁
        super.doSomeThing();
        ...
    }
}

Lock usage rules:

  • For a mutable state variable that may be accessed simultaneously by multiple threads, the same lock needs to be held when accessing it. This can also be the case that the variable is protected by this lock.
  • Each shared and mutable state variable should be protected by only one lock, so that maintainers know which lock it is.
  • For each invariant condition involving multiple variables, all variables involved need to be protected by the same lock.

Notice:

There is no intrinsic relationship between an object's built-in locks and the object's state. When acquiring the lock associated with an object, it does not prevent other threads from accessing the object, but only prevents other threads from acquiring the same lock.

Which lock is used can be marked with the @GuardBy tag.

Guess you like

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