显式锁的使用

1、使用ReentrantLock类

     它与synchronized有相似的功能效果,使用lock方法开启同步区域的起始边界,使用unlock方法开启同步区域的结束边界,两个方法成对出现。synchronized使用wait/notify或wait/notifyAll可以实现等待/通知模型。ReentrantLock类也可以借助Condition类的对象,实现等待/通知模型。Object类的wait方法相当于Condition类的await方法,Object类的notify方法相当于Condition类的signal方法,Object类的notifyAll方法相当于Condition类的signalAll方法。在同一个锁下,Condition对象可以有多个。

多生产者/多消费者双条件的等待通知模型示例代码:

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

public class Resource {
private static int resource=0;
private static int top=10;
private static int low=0;
public static final ReentrantLock lock=new ReentrantLock();
public static final Condition wc=lock.newCondition();
public static final Condition rc=lock.newCondition();

public static int getResource() {
return resource;
}

public static void setResource(int resource) {
Resource.resource = resource;
}

public static int getLow() {
return low;
}

public static void setLow(int low) {
Resource.low = low;
}

public static int getTop() {
return top;
}

public static void setTop(int top) {
Resource.top = top;
}
}
public class Producer implements Runnable{
@Override
public void run() {
Resource.lock.lock();
if(Resource.getResource()>=Resource.getTop()) {
System.out.println(Thread.currentThread().getName()+" producer thread is waiting");
try {
Resource.wc.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(Resource.getResource()<Resource.getTop()) {
Resource.setResource(Resource.getResource()+1);
System.out.println(Thread.currentThread().getName()+" producer thread is working");
Resource.rc.signalAll();
}
Resource.lock.unlock();
}

}
public class Consumer implements Runnable{

@Override
public void run() {
Resource.lock.lock();
if(Resource.getResource()<=Resource.getLow()) {
System.out.println(Thread.currentThread().getName()+" comsumer thread is no resource to buy, so notify all thread");
try {
Resource.rc.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(Resource.getResource()>Resource.getLow()) {
Resource.setResource(Resource.getResource()-1);
System.out.println(Thread.currentThread().getName()+" comsumer thread is buying");
Resource.wc.signalAll();
}
Resource.lock.unlock();
}

}
import java.util.ArrayList;

public class CPTest {

public static void main(String[] args) {
Consumer c=new Consumer();
Producer p=new Producer();
ArrayList<Thread> list =new ArrayList<Thread>();
for(int i=0;i<30;i++) {
list.add(new Thread(p));
list.add(new Thread(c));
}
for(int i=0;i<list.size();i++) {
list.get(i).start();
}

}

}

锁Lock分为公平锁和非公平锁,公平锁表示获取锁的顺序是按照线程加锁的顺序来分配的,即FIFO;非公平锁是一种获取锁的抢占机制,随机获得,可能会导致某些线程一直拿不到锁。非公平锁的运行结果基本上是乱序的,公平锁的运行结果基本呈现有序状态。

     getHoldCount方法是查询当前线程保持此锁定的个数,即调用lock方法的次数。

     getQueueLength方法是查询等待获取当前锁的线程估计数。

     getWaitQueueLength(Condition condition)是查询等待lock相关condition的线程估计数。

      hasQueueThread(Thread thread)是查询线程thread是否正在等待获取此lock。

      hasQueueThreads方法是查询是否有线程正在等待获取此锁。

      hasWaiters(Condition condition)查询是否有线程正在等待与此lock有关的condition条件。

      isFair方法是判断此lock是不是公平锁。

      isHeldByCurrentThread方法是查询当前线程是否保持此lock。

      isLocked方法是查询此锁定是否由任意线程保持。

      lockInterruptiby方法:如果线程未被中断,则获取锁定;如果已经被中断,则抛出异常。

      tryLock方法:仅在调用时,lock没有被另外一个线程保持的情况下,才获取lock。

      tryLock(long timeout,TimeUnit unit):如果lock在给定的时间内没有被另一个线程保持,且当前线程未被中断,则获取该lock。   

      condition.awaitUntil(Date date):程序运行至此方法处会进入等待状态,如果在date时间段内没有被唤醒,则date之后自动唤醒,继续后续执行。如果在date时间段内被唤醒,则继续后续执行。如果被唤醒后没有拿到lock,则等待获取cpu执行时间。

2、使用ReentrantReadWriteLock类

     这个类是读写锁机制,与读操作相关的锁也称为共享锁,与写操作相关的锁也称为排他锁,除了读锁与读锁之间不互斥,其他情况均互斥。这种锁特别适合读写分离,并且读操作的占比越高,运行效率越高。

     读锁加锁机制:

     (new ReentrantReadWriteLock()).readLock().lock();

  //同步区域

     (new ReentrantReadWriteLock()).readLock().unlock();

      写锁加锁机制:

    (new ReentrantReadWriteLock()).writeLock().lock();

  //同步区域

     (new ReentrantReadWriteLock()).writeLock().unlock();

3、锁的分类

      锁分为显式锁和隐式锁,显式锁就是ReentrantLock和ReentrantReadWriteLock,隐式锁是synchronized。隐式锁是不公平锁,显式锁默认是不公平锁,但是可以支持公平锁。隐式锁synchronized是不可中断的,Lock的是可以中断的。从使用方式上来讲,隐式锁synchronized操作上更加容易;显式锁在操作上需要更加细致,如加锁和释放锁,需要跟try...catch...finally联用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值