1. 首页
  2. 乌拉客

ReentrantReadWriteLock类的使用

ReentrantReadWriteLock与ReentrantLock的区别:

ReentrantLock:同一时间只能有一个线程执行ReentrantLock.lock()后面的代码,这样虽然可以保证线程安全,但程序的运行效率却比较低。

ReentrantReadWriteLock:有两种锁也就是分别有读和写两种锁,在不需要操作实例变量时,可用读锁,在操作实例变量时,用写锁,这样就可以提升程序的运行效率。

共享锁:读相关的锁就叫共享锁。

排他锁:写相关的锁就叫排他锁。

我们首先看一下共享锁:

/**
 * 用户登录
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:35
 * @since 1.0.0
 */
public class Userinfo {

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void test() {
        try {
            lock.readLock().lock();
            System.out.println(String.format("获得锁: %s\t 时间:%s", Thread.currentThread().getName(),System.currentTimeMillis()));
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.readLock().unlock();
        }
    }
}
/**
 * 管理用户请求
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:44
 * @since 1.0.0
 */
public class RequestAdmin extends Thread {

    private Userinfo userinfo;

    public RequestAdmin(Userinfo userinfo) {
        this.userinfo = userinfo;
    }

    @Override
    public void run() {
        userinfo.test();
    }
}
/**
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 13:35
 * @since 1.0.0
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Userinfo userinfo = new Userinfo();
        RequestAdmin requestAdmin = new RequestAdmin(userinfo);
        requestAdmin.start();
        RequestAdmin requestAdmin2 = new RequestAdmin(userinfo);
        requestAdmin2.start();
    }
}
获得锁: Thread-0	 时间:1490141675565
获得锁: Thread-1	 时间:1490141675570

我们看两个线程是异步执行的,这就是共享锁的好处,多个线程可以同时执行lock()方法后面的代码,提高程序的执行效率。下面我们看一下排他锁:

/**
 * 用户登录
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:35
 * @since 1.0.0
 */
public class Userinfo {

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void test() {
        try {
            lock.writeLock().lock();
            System.out.println(String.format("获得锁: %s\t 时间:%s", Thread.currentThread().getName(),System.currentTimeMillis()));
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.writeLock().unlock();
        }
    }
}
/**
 * 管理用户请求
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:44
 * @since 1.0.0
 */
public class RequestAdmin extends Thread {

    private Userinfo userinfo;

    public RequestAdmin(Userinfo userinfo) {
        this.userinfo = userinfo;
    }

    @Override
    public void run() {
        userinfo.test();
    }
}
/**
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 13:35
 * @since 1.0.0
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Userinfo userinfo = new Userinfo();
        RequestAdmin requestAdmin = new RequestAdmin(userinfo);
        requestAdmin.start();
        RequestAdmin requestAdmin2 = new RequestAdmin(userinfo);
        requestAdmin2.start();
    }
}
获得锁: Thread-0	 时间:1490141992346
获得锁: Thread-1	 时间:1490142002380

我们看输出是同步执行的。这也是排他锁的特性,如果线程中有操作实例变量的操作,为了保证线程安全可以用排他锁。

共享锁和排他锁也是互斥锁。这句话的意思是说如果线程已经获取到了共享锁,但程序没有执行完,那么此时,其它线程在获取排他锁时,是获取不到的,只能等待共享锁释放后才可获取到。

/**
 * 用户登录
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:35
 * @since 1.0.0
 */
public class Userinfo {

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void read() {
        try {
            lock.readLock().lock();
            System.out.println(String.format("获得共享锁: %s\t 时间:%s", Thread.currentThread().getName(),System.currentTimeMillis()));
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.readLock().unlock();
        }
    }

    public void write() {
        try {
            lock.writeLock().lock();
            System.out.println(String.format("获得排他锁: %s\t 时间:%s", Thread.currentThread().getName(),System.currentTimeMillis()));
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.writeLock().unlock();
        }
    }
}
/**
 * 管理用户请求
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:44
 * @since 1.0.0
 */
public class RequestAdmin extends Thread {

    private Userinfo userinfo;

    public RequestAdmin(Userinfo userinfo) {
        this.userinfo = userinfo;
    }

    @Override
    public void run() {
        userinfo.read();
    }
}
/**
 * 用户请求
 *
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-15 10:44
 * @since 1.0.0
 */
public class RequestUser extends Thread {

    private Userinfo userinfo;

    public RequestUser(Userinfo userinfo) {
        this.userinfo = userinfo;
    }

    @Override
    public void run() {
        userinfo.write();
    }
}
/**
 * @author Sama
 * @author admin@jilinwula.com
 * @date 2017-03-20 13:35
 * @since 1.0.0
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Userinfo userinfo = new Userinfo();
        RequestAdmin requestAdmin = new RequestAdmin(userinfo);
        requestAdmin.start();
        RequestUser requestUser = new RequestUser(userinfo);
        requestUser.start();
    }
}
获得共享锁: Thread-0	 时间:1490142647525
获得排他锁: Thread-1	 时间:1490142657570

原创文章,作者:二十四分之七倍根号六,如若转载,请注明出处:http://jilinwula.com/130.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

邮件:admin@jilinwula.com

QQ:923505769

 

QR code