ReetranLock比synchronized更加灵活
synchronized 与wait,nodify,nodifyAll方法相结合实现通知等待
ReetranLock与Condition对象的await,signal,signalAll也可实现此功能,而且可以选择性的进行线程通知,唤醒指定的线程。
举例说明,实现生产者、消费者多对多打印
package lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set() {
try {
lock.lock();
while (hasValue == true) {
System.out.println("--");
condition.await();
}
System.out.println("-");
hasValue=true;
condition.signalAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
try {
lock.lock();
while (hasValue == false) {
System.out.println("**");
condition.await();
}
System.out.println("*");
hasValue=false;
condition.signalAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
package lock;
public class Run {
public static void main(String[] args) {
MyService service = new MyService();
ThreadAAA[] a = new ThreadAAA[10];
ThreadBBB[] b = new ThreadBBB[10];
for (int i=0;i<10;i++) {
a[i] = new ThreadAAA(service);
b[i] = new ThreadBBB(service);
a[i].start();
b[i].start();
}
}
}
class ThreadAAA extends Thread{
private MyService service;
public ThreadAAA (MyService service) {
this.service = service;
}
public void run() {
while (true) {
service.set();
}
}
}
class ThreadBBB extends Thread{
private MyService service;
public ThreadBBB (MyService service) {
this.service = service;
}
public void run() {
while (true) {
service.get();
}
}
}
公平锁与非公平锁
公平锁表示线程获取锁的顺序是按照线程加锁的顺序来的,先进先出
非公平锁是一种抢占机制,随机获得锁
设置
private ReentrantLock lock = new ReentrantLock(true);
true为公平锁,false为非公平锁。、
优缺点:
非公平锁性能高于公平锁性能。首先,在恢复一个被挂起的线程与该线程真正运行之间存在着严重的延迟。而且,非公平锁能更充分的利用cpu的时间片,尽量的减少cpu空闲的状态时间。
使用场景
使用场景的话呢,其实还是和他们的属性一一相关,举个栗子:如果业务中线程占用(处理)时间要远长于线程等待,那用非公平锁其实效率并不明显,但是用公平锁会给业务增强很多的可控制性。
使用ReetranReadWriteLock实现读写锁,提高了ReetranLock 的效率,因为ReetranLock是排他锁
多个读是共享锁,写锁是排他锁
ReetranReadWriteLock lock = new ReetranReadWriteLock();
lock.readLock().lock() 获取读锁
lock.writeLock().lock() 获取写锁