多线程同步 (二)——ReentrantLock类

多线程同步 (一)——synchronized关键字,可以通过使用synchronized关键字实现线程之间的同步,
使用Lock也可以达到同样的效果,本篇博客主要是关于Lock接口的子类ReentrantLock的使用,
由于对多线程了解的不足,本文仅作为自我学习总结,如有不正确的地方欢迎大家批评指正。

1. ReentrantLock

由Java api,ReetrantLock是Lock接口的子类,称为“重入锁”,是指当线程获取锁之后,可以再次获取该锁。
在RentrantLock类中有两个最基本的方法:

lock(): 获取锁, 根据Java api, 该方法的定义如下:
Acquires the lock.

Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.

If the current thread already holds the lock then the hold count is incremented by one and the method returns immediately.

If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired, at which time the lock hold count is set to one.

因此,lock()方法的作用是获取锁。
如果锁没有被其他线程占据,则获取锁,并将锁计数器设置为1;
如果锁已经被当前线程占据,则可以再次获取该锁,锁计数器自增;
如果锁已经被其他线程占据,则当前线程变为不可被调度,直到成功获取锁。

unlock(): 释放锁, 根据Java api, 该方法的定义如下:
Attempts to release this lock.

If the current thread is the holder of this lock then the hold count is decremented. 

If the hold count is now zero then the lock is released.

If the current thread is not the holder of this lock then IllegalMonitorStateException is thrown.

因此,unlock()方法的作用是释放锁。
如果锁已经被当前线程占据,则锁计数器自减,当锁计数器为0时,锁被成功释放;
如果锁不被当前线程占据,则抛出IllegalMonitorStateException异常。

此外,由Java api,在使用Lock的时候需要注意:

When locking and unlocking occur in different scopes, care must be taken to ensure that all code that is executed while the lock is held is protected by try-finally or try-catch to ensure that the lock is released when necessary.

因此,请一定要成对使用lock()和unlock(),以保证锁的释放,否则容易导致死锁的发生。

2. 代码实例

功能:

多线程同步 (一)——synchronized关键字创建3个线程,对变量num进行有序+1操作,各循环100次。

代码示例:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/*
 * 使用ReentrantLock类
 */
public class Test_reentrantLock implements Runnable {

    private int num = 0;
    private Lock lock = new ReentrantLock();

    @Override
    public void run() {
        printNum();

    }
    public void printNum(){
        try {
            lock.lock();
            for(int i=0; i<100; i++){
                num++;
                System.out.println(num);
            }
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        Test_reentrantLock r = new Test_reentrantLock();
        for(int i=0; i<3; i++){

            Thread t = new Thread(r);
            t.start();
        }
    }
}

运行结果:

扫描二维码关注公众号,回复: 2882776 查看本文章

这里写图片描述

……中间打印省略……

这里写图片描述

共享变量num实现了有序递增,与使用synchrinized关键字效果是一样的。

这里写图片描述

猜你喜欢

转载自blog.csdn.net/gxx_csdn/article/details/79261157