ReentrantReadWriteLock类的使用

/ 多线程 / 没有评论 / 334浏览

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