java: multithreaded synchronization to ensure the operation

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/sinat_31057219/article/details/102729531

reference:

Android multithreaded operations to ensure synchronization (sync lock of both kinds)

Synchronized manner

1. Using the synchronized keyword.
Modified method using the synchronized keyword synchronized execution must wait for the completion of a synchronized execution will proceed,
if the thread is blocked during execution, he would have been on hold waiting here is not particularly recommend this way ,
if you need must be guaranteed under the circumstances and to ensure that data synchronization does not occur in other cases the user can not complete the operation in case you can use, it can be used.
This keyword is generally used for singleton thread ensure safe use.
No manual release or off, is automatically released when the operation is completed by reference

2. Use lock the lock object.
After creating an object using Lock.lock () method lock,
Note: To unlock the lock must be in a finally block () operation.
If you do not manually release the lock will always exist references, it will cause a lot of unexpected problems. Such as might frequently GC, serious will ANR.

Note: Lock on selected object and the synchronized keyword:

a. is preferably not both, java.util.concurrent package uses a mechanism provided to help users deal with all the lock code.
b. If the synchronized keyword to meet the needs of users, use synchronized, because it can simplify the code
c. If you need more advanced features, use ReentrantLock class, this time to pay attention to timely release the lock, otherwise there will be a deadlock, usually in a finally release the lock

Multithreading unsafe Example:

public class TestActivity extends AppCompatActivity {

    private static final String TAG = TestActivity.class.getSimpleName();

    private int a = 0;

    private void writeLog() {
        for (int i = 0; i < 2; i++) {
            try {
                a++;
                Log.e(TAG, i + " ++++++++============" +
                        Thread.currentThread().getName() + 
						"    write 开始:" + a);

                Thread.sleep(new Random().nextInt(1000));

                a--;
                Log.e(TAG, i + " ++++++++============" +
                        Thread.currentThread().getName() + 
						"    write 结束:" + a);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void readLog() {
        for (int i = 0; i < 2; i++) {
            try {
                Log.e(TAG, i + " --------============" +
                        Thread.currentThread().getName() + 
						"    read 开始:" + a);

                Thread.sleep(new Random().nextInt(1000));

                Log.e(TAG, i + " --------============" +
                        Thread.currentThread().getName() + 
						"    read 结束:" + a);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class WriteRunnable implements Runnable {
        @Override
        public void run() {
            writeLog();
        }
    }

    class ReadRunnable implements Runnable {
        @Override
        public void run() {
            readLog();
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WriteRunnable writeRunnable = new WriteRunnable();
        ReadRunnable readRunnable = new ReadRunnable();
        for (int i = 0; i < 2; i++) {
            new Thread(writeRunnable).start();
            new Thread(readRunnable).start();
        }
    }
    //不安全:
    //0 ++++++++============Thread-6    write 开始:1
    //0 --------============Thread-7    read 开始:1
    //0 ++++++++============Thread-8    write 开始:2
    //0 --------============Thread-9    read 开始:2
    //0 ++++++++============Thread-8    write 结束:1
    //1 ++++++++============Thread-8    write 开始:2
    //1 ++++++++============Thread-8    write 结束:1
    //0 --------============Thread-7    read 结束:1
    //1 --------============Thread-7    read 开始:1
    //0 --------============Thread-9    read 结束:1
    //1 --------============Thread-9    read 开始:1
    //0 ++++++++============Thread-6    write 结束:0
    //1 ++++++++============Thread-6    write 开始:1
    //1 --------============Thread-7    read 结束:1
    //1 ++++++++============Thread-6    write 结束:0
    //1 --------============Thread-9    read 结束:0
}

In the write time, a ++, after a--, a value of 2 should not appear the phenomenon should not be any write is not over, began to read

synchronized with thread safety


public class TestActivity extends AppCompatActivity {

    private static final String TAG = TestActivity.class.getSimpleName();

    private int a = 0;

    //synchronized这个关键字可以直接加到方法上也可使用synchronized代码块
    //这里为方法上
    private synchronized void writeLog() {
        for (int i = 0; i < 2; i++) {
            try {
                a++;
                Log.e(TAG, i + " ++++++++============" +
                        Thread.currentThread().getName() + 
						"    write 开始:" + a);

                Thread.sleep(new Random().nextInt(1000));

                a--;
                Log.e(TAG, i + " ++++++++============" +
                        Thread.currentThread().getName() + 
						"    write 结束:" + a);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void readLog() {
        //synchronized这个关键字可以直接加到方法上也可使用synchronized代码块
        //这里为代码块
        synchronized (this) {
            for (int i = 0; i < 2; i++) {
                try {
                    Log.e(TAG, i + " --------============" +
                            Thread.currentThread().getName() + 
							"    read 开始:" + a);

                    Thread.sleep(new Random().nextInt(1000));

                    Log.e(TAG, i + " --------============" +
                            Thread.currentThread().getName() + 
							"    read 结束:" + a);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class WriteRunnable implements Runnable {
        @Override
        public void run() {
            writeLog();
        }
    }

    class ReadRunnable implements Runnable {
        @Override
        public void run() {
            readLog();
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WriteRunnable writeRunnable = new WriteRunnable();
        ReadRunnable readRunnable = new ReadRunnable();
        for (int i = 0; i < 2; i++) {
            new Thread(writeRunnable).start();
            new Thread(readRunnable).start();
        }
    }
    //线程安全
    //0 ++++++++============Thread-6    write 开始:1
    //0 ++++++++============Thread-6    write 结束:0
    //1 ++++++++============Thread-6    write 开始:1
    //1 ++++++++============Thread-6    write 结束:0
    //0 --------============Thread-7    read 开始:0
    //0 --------============Thread-7    read 结束:0
    //1 --------============Thread-7    read 开始:0
    //1 --------============Thread-7    read 结束:0
    //0 ++++++++============Thread-8    write 开始:1
    //0 ++++++++============Thread-8    write 结束:0
    //1 ++++++++============Thread-8    write 开始:1
    //1 ++++++++============Thread-8    write 结束:0
    //0 --------============Thread-9    read 开始:0
    //0 --------============Thread-9    read 结束:0
    //1 --------============Thread-9    read 开始:0
    //1 --------============Thread-9    read 结束:0
}

ReentrantLock and thread safety: reentrant lock synchronization

We added a java.util.concurrent package in JavaSE5.0 in support synchronization.

ReentrantLock class is reentrant, exclusive, to achieve lock Lock interface,
it is fast and using synchronized methods have the same basic behavior and semantics, and its ability to expand.

Common method ReenreantLock class are:

ReentrantLock (): create a ReentrantLock instance
lock (): get the lock
unlock (): release the lock

Example:


public class TestActivity extends AppCompatActivity {

    private static final String TAG = TestActivity.class.getSimpleName();

    private int a = 0;

    private Lock lock = new ReentrantLock();

    private void writeLog() {
        for (int i = 0; i < 2; i++) {
            try {
                lock.lock();    //加锁
                a++;
                Log.e(TAG, i + " ++++++++============" +
                        Thread.currentThread().getName() +
                        "    write 开始:" + a);

                Thread.sleep(new Random().nextInt(1000));

                a--;
                Log.e(TAG, i + " ++++++++============" +
                        Thread.currentThread().getName() +
                        "    write 结束:" + a);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();  //释放锁
            }
        }
    }

    private void readLog() {
        for (int i = 0; i < 2; i++) {
            try {
                lock.lock();    //加锁

                Log.e(TAG, i + " --------============" +
                        Thread.currentThread().getName() +
                        "    read 开始:" + a);

                Thread.sleep(new Random().nextInt(1000));

                Log.e(TAG, i + " --------============" +
                        Thread.currentThread().getName() +
                        "    read 结束:" + a);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();  //释放锁
            }
        }
    }

    class WriteRunnable implements Runnable {
        @Override
        public void run() {
            writeLog();
        }
    }

    class ReadRunnable implements Runnable {
        @Override
        public void run() {
            readLog();
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WriteRunnable writeRunnable = new WriteRunnable();
        ReadRunnable readRunnable = new ReadRunnable();
        for (int i = 0; i < 2; i++) {
            new Thread(writeRunnable).start();
            new Thread(readRunnable).start();
        }
    }
    //线程安全
    //0 ++++++++============Thread-6    write 开始:1
    //0 ++++++++============Thread-6    write 结束:0
    //1 ++++++++============Thread-6    write 开始:1
    //1 ++++++++============Thread-6    write 结束:0
    //0 --------============Thread-7    read 开始:0
    //0 --------============Thread-7    read 结束:0
    //1 --------============Thread-7    read 开始:0
    //1 --------============Thread-7    read 结束:0
    //0 ++++++++============Thread-8    write 开始:1
    //0 ++++++++============Thread-8    write 结束:0
    //1 ++++++++============Thread-8    write 开始:1
    //1 ++++++++============Thread-8    write 结束:0
    //0 --------============Thread-9    read 开始:0
    //0 --------============Thread-9    read 结束:0
    //1 --------============Thread-9    read 开始:0
    //1 --------============Thread-9    read 结束:0
}

Guess you like

Origin blog.csdn.net/sinat_31057219/article/details/102729531