[Translation] thread safe in Java

Original www.journaldev.com/1061/thread...

Thread safety in Java

Thread safety in Java is a very important topic. Java uses Threads provide support for multi-threaded environment, we know that the same variable multiple threads to create a shared object, when the thread to read and update data, which may result in inconsistent data.

Thread Safety

Reasons for the discrepancy data field is not updated any atom process, it requires three steps: first read the current value, the second step is to do the necessary actions to obtain the updated values, the third step is to update the reference value is assigned to the field .

Let's use a simple program to check what multithreading update the shared data.

public class ThreadSafety {

    public static void main(String[] args) throws InterruptedException {
    
        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1");
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        //wait for threads to finish processing
        t1.join();
        t2.join();
        System.out.println("Processing count="+pt.getCount());
    }

}

class ProcessingThread implements Runnable{
    private int count;
    
    @Override
    public void run() {
        for(int i=1; i < 5; i++){
            processSomething(i);
        	count++;
        }
    }

    public int getCount() {
        return this.count;
    }

    private void processSomething(int i) {
        // processing some job
        try {
            Thread.sleep(i*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
}
复制代码

In the above for loop, we count increased by four times, because we have two threads, so the value after both threads finished execution should be 8. But when you run the above procedure several times, you will find that the value of count varies between 6,7,8. This happens because the count ++ appears to be an atomic operation, in fact, is not and can cause data corruption.

Thread safety in Java

Java thread-safe in our program is to make the process safe to use in a multithreaded environment, we can make the security thread in different ways.

  • Java synchronization is the simplest and most widely used tool for thread-safe.
  • Use java.util.concurrent.atomic Atomic Wrapper class package. For example AtomicInteger.
  • Use java.util.concurrent.locks package lock.
  • Use thread-safe collection classes, check out this article to learn ConcurrentHashMap usage to ensure thread safety.
  • Use the variable with the volatile keyword so that each thread to read data from memory, instead of reading from the thread cache.

Java synchronized

We can use the synchronization tools to achieve thread-safe, JVM ensure synchronization code can only be executed by a thread. java synchronization code used to create the synchronized keyword, which uses an internal object lock or class lock to ensure that only one thread is executing the code synchronization.

  • Java synchronization when locking and unlocking resources work, before entering any thread synchronization code, it gets the object lock, release resources at the end of the code execution to another thread locked. At the same time, other threads in a wait state in order to lock synchronization resources.
  • We have two ways to use the synchronized keyword, one is the whole complete synchronization method, and the other is to create a synchronized block.
  • When a method is a synchronous method, the current object is locked it, if it is a static method, the lock of this class, it is preferable to use a synchronization code part needs to lock the block synchronization process.
  • When we create a synchronized block, we need to provide the resources to acquire the lock, it can be any Object field XYZ.class or class.
  • synchronized (this) lock object before entering the synchronized block.
  • You should use the lowest level of the lock, for example: if a class has multiple synchronized block and one of the current object is locked, the other synchronization code block can not be executed by another thread. When we lock an object, it locks the current object will get all the fields.
  • Java synchronization to reduce the cost of performance to ensure data integrity, it should be used only when absolutely necessary.
  • Java synchronization is only valid in the same JVM, so if you need to lock some resources in multiple JVM environment, Java synchronization will fail, you may need to think about some global locking mechanism.
  • Java synchronization can lead to a deadlock, please see the related java deadlock and how to avoid deadlocks posts.
  • Java synchronized keyword can not be used to construct the functions and variables.
  • Better to create a virtual private object synchronization code block for a reference so that it can not be any other code changes. For example, if the setter being synchronized Object, which can be modified by other reference codes, and the synchronization code blocks in parallel.
  • We should not use any object in the constant pool maintenance, such as String should not be used to synchronize, because if any other code is also locked in the same String, it will try to acquire a lock even if both references to the same String object from the pool code is not related, they will be locked to each other.

Here is the code we need to change the above program to make it thread safe.


    //dummy object variable for synchronization
    private Object mutex=new Object();
    ...
    //using synchronized block to read, increment and update count value synchronously
    synchronized (mutex) {
            count++;
    }
    
复制代码

Let's look at some examples of sync and what we can learn from.


public class MyObject {
 
  // Locks on the object's monitor
  public synchronized void doSomething() { 
    // ...
  }
}
 
// Hackers code
MyObject myObject = new MyObject();
synchronized (myObject) {
  while (true) {
    // Indefinitely delay myObject
    Thread.sleep(Integer.MAX_VALUE); 
  }
}

复制代码

Please note that the code hackers are trying to lock myObject instances, once locked, it will never release it leads to doSomething () method blocks while waiting for the lock, which will lead to a deadlock and the system continues to cause a denial of service (DoS)).

Guess you like

Origin juejin.im/post/5d53d96df265da03eb13c1d4