21 ReentrantLock(重入锁) & ReentrantReadWriteLock(读写锁)

 锁(重入锁,读写锁)

它们具有比synchronized更为强大的功能,并且有嗅探锁定、多路分支等功能。

重入锁,在需要进行同步的代码部分加上锁定,但不要忘记最后一定要释放锁定,不然会造成锁永远无法释放,其他线程永远进不去的结果。


  

package edu.sdut.lock;

 

 

import java.util.concurrent.CopyOnWriteArrayList;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

 

public class UseReentrantLock {

private Lock lock = new ReentrantLock();

public void method1(){

try {

lock.lock();

System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method1..");

Thread.sleep(1000);

System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method1..");

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public void method2(){

try {

lock.lock();

System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method2..");

Thread.sleep(2000);

System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method2..");

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public static void main(String[] args) {

 

final UseReentrantLock ur = new UseReentrantLock();

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

ur.method1();

ur.method2();

}

}, "t1");

 

t1.start();

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

//System.out.println(ur.lock.getQueueLength());

}

}

 

锁的等待/通知

在使用Lock的时候,可以使用一个新的等待/通知类,Condition,这个Condition一定是针对具体,某一把锁的。也就是在只有锁的基础上才会产生Condition.

多个Condition的使用:

package edu.sdut.lock;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class UseManyCondition {

private ReentrantLock lock = new ReentrantLock();

private Condition c1 = lock.newCondition();

private Condition c2 = lock.newCondition();

public void m1(){

try {

lock.lock();

System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m1等待..");

//等待

c1.await();

System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m1继续..");

} catch (Exception e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public void m2(){

try {

lock.lock();

System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m2等待..");

c1.await();

System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m2继续..");

} catch (Exception e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public void m3(){

try {

lock.lock();

System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m3等待..");

c2.await();

System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m3继续..");

} catch (Exception e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public void m4(){

try {

lock.lock();

System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");

//唤醒  相当于synchronized中的 wait/notify

//lock.signal();

c1.signalAll();

} catch (Exception e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public void m5(){

try {

lock.lock();

System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");

c2.signal();

} catch (Exception e) {

e.printStackTrace();

} finally {

lock.unlock();

}

}

public static void main(String[] args) {

final UseManyCondition umc = new UseManyCondition();

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

umc.m1();

}

},"t1");

Thread t2 = new Thread(new Runnable() {

@Override

public void run() {

umc.m2();

}

},"t2");

Thread t3 = new Thread(new Runnable() {

@Override

public void run() {

umc.m3();

}

},"t3");

Thread t4 = new Thread(new Runnable() {

@Override

public void run() {

umc.m4();

}

},"t4");

Thread t5 = new Thread(new Runnable() {

@Override

public void run() {

umc.m5();

}

},"t5");

t1.start();// c1

t2.start();// c1

t3.start();// c2

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

t4.start();// c1

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

t5.start();// c2

}

}

 

 

 Lock/Condition其他方法和使用

Lock lock = new ReentrantLock(boolean isFair);

lock用法:

tryLock();尝试获得锁

 ReentrantReadWriteLock(读写锁)

读写锁ReentrantReadWriteLock,其核心就是实现读写分离的锁,在高并发访问下,尤其是读多写少的情况下,性能要远高于重写锁。

对于Synchronized、ReentrantLock,同一时间内只能有一个线程访问被锁定的代码,那么读写锁则不同,其本质是分离两个锁,即读锁和写锁。在读锁下,多个线程呢个可以并发的进行访问,但是在写锁的时候,只能顺序的访问。

读读共享、写写互斥、读写互斥

import java.util.concurrent.locks.ReentrantReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;

import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

public class UseReentrantReadWriteLock {

private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

private ReadLock readLock = rwLock.readLock();

private WriteLock writeLock = rwLock.writeLock();

public void read(){

try {

readLock.lock();

System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");

Thread.sleep(3000);

System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");

} catch (Exception e) {

e.printStackTrace();

} finally {

readLock.unlock();

}

}

public void write(){

try {

writeLock.lock();

System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");

Thread.sleep(3000);

System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");

} catch (Exception e) {

e.printStackTrace();

} finally {

writeLock.unlock();

}

}

public static void main(String[] args) {

final UseReentrantReadWriteLock urrw = new UseReentrantReadWriteLock();

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

urrw.read();

}

}, "t1");

Thread t2 = new Thread(new Runnable() {

@Override

public void run() {

urrw.read();

}

}, "t2");

Thread t3 = new Thread(new Runnable() {

@Override

public void run() {

urrw.write();

}

}, "t3");

Thread t4 = new Thread(new Runnable() {

@Override

public void run() {

urrw.write();

}

}, "t4");

//t1.start();

//t2.start();

//t1.start(); // R

//t3.start(); // W

t3.start();

t4.start();

}

}

猜你喜欢

转载自blog.csdn.net/txgANG/article/details/80915492