synchronization of threads

Thread synchronization is to prevent multiple threads from accessing the same data object and causing damage to the data

1. Problems caused by parallel execution of threads:

public class FanXing {
    private int i = 0;
    public static void main(String[] args) throws InterruptedException {
        FanXing fanXing = new FanXing();
        int k = 0;
        Thread t1 = new Thread(){
            @Override
public void run() {
                for (int i=0;i<100000;i++){
                    fanXing.f();
}                            
            }
        };
        Thread t2 = new Thread(){
            @Override
public void run() {
                for (int i=0;i<100000;i++){
                    fanXing.f();
}                            
            }
        } ;
         t1.start() ;
 t2.start () ;
         Thread.sleep ( 5000 ) ;
 System.out .println ( "The final result is :" +fanXing.getI()) ; }
 public
     int getI () {
         return i ;
 }
     public void f (){
         i ++ ;
 }                            
}

The above code has two threads doing auto-increment operations on an object property at the same time, but the final result is always less than 200000


What is this asking, because the auto-increment operation is not atomic, it is divided into three operations, value, auto-increment, and assignment. Imagine if the first thread gets the value of 100 and executes the auto-increment step, another thread gets the value and auto-increments to complete the operation (currently the value is 101), and the first thread is auto-incrementing and writes back 101 , while the second thread also writes 101 back to memory. It can be seen that the data has been wrong.

2. Thread synchronization and object lock

    Every object in Java has a built-in lock. When a program runs a non-static synchronized method, an object lock with the executing class is automatically acquired. Also known as acquiring an object lock.

    An object has only one lock. So when a thread acquires the thread lock, if other threads want to acquire the lock, they must wait for the thread that acquired the lock to release the lock.

About locks:

    1. Only methods can be synchronized, not variables or classes

    2. When synchronizing a method, determine whether the method needs to be synchronized. The method that does not need synchronization does not need to be locked, because the lock also has overhead

    3. If a thread acquires the object lock of this object, other threads can only execute the unsynchronized method of the object

    4. A thread can acquire multiple locks, such as calling a synchronized method of another object in a synchronized method

    5. When the thread sleeps, the object lock it holds will not be released

For the above code, we can lock the method so that it can be synchronized and get the correct result

public synchronized void f(){
    i++;
}

Just add the synchronized keyword to the method


This gives the correct result

3. Synchronization of static methods

    Because static methods belong to the class itself, not to an object (although you can call it with an object), for static methods, you need to lock the class, which is the Class object of this class

public static void f(){
    i++;
}

So for static methods, we need to lock the class, that is, lock the Class object of this class in the synchronized keyword, like this

public static void f(){
    synchronized (FanXing.class) {
        i++;
    }
}

四、线程同步小结

    1、线程同步就是为了避免多个线程对同一个资源的访问而可能造成的数据破坏

    2、线程同步是根据对象锁实现的,每个对象只有一个锁,所以当一个线程得到了该对象的锁,其他线程想访问该对象的同步方法时,只能等待获得锁的线程对该锁的释放

    3、对于非静态方法,只要锁住对象即可,而对于静态方法,则需要锁住该类

    4、当多个线程等待一个对象锁时,没有获得到锁的对象将阻塞

Guess you like

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