java中的锁:synchronized与ReentrantLock

一、synchronized

1、具体的实现方式有:
A:同步代码块
synchronized(锁旗标/监视哨/任意对象){
	//需要同步的代码块
}

B:同步方法
[访问修饰符] synchronized 方法返回值的数据类型 方法名([参数列表]){
	//需要同步的代码
}
2、同步代码块和同步函数的区别:
  A:语法不同  
  B:同步代码块的锁是任意对象,同步的实例方法使用锁是固定的:this
注:
   同步的实例方法使用的锁是this.  
   同步的静态方法使用的锁是:当前静态方法所在的 类名.class(字节码文件对象)

二、ReentrantLock

1.实例化锁对象
private final Lock lock=new ReentrantLock();
2.根据锁对象获取监视器对象
Condition producer_condition=lock.newCondition();
Condition consumer_condition=lock.newCondition();
3.锁的使用
(1)、让生成者线程使用的方法,完成生产任务
public  void set(String name,char sex){
    //a.获取锁对象
    lock.lock();
    try{
        //判断是否生产过
        while(this.isProduce){
            //b、让当前线程(生产者线程)等待
            producer_condition.await();
        }
        this.name=name;
        this.sex=sex;
        //将是否生产过的标记置为true,表示已经生产过了.
        this.isProduce=true;
        //c、唤醒消费者线程对象
        consumer_condition.signal();
    }finally{
        //d、释放锁
        lock.unlock();
    }
}
(2)、消费者线程完成消费任务时调用的方法
public  void out(){
    //a.获取锁
    lock.lock();
    try{
        //如果没有生产过,则消费者线程等待
        while(!this.isProduce){
            //b、让消费者线程对象
            consumer_condition.await();
        }
        //如果已经消费过了,则将已经生成过的标志置为false,表示没有生成过
        this.isProduce=false;
        //c、唤醒生产者线程对象
        producer_condition.signal();
    }finally{
        //d、释放锁
        lock.unlock();
    }
}
(3)、启动线程
Thread t1=new Thread(new MyRunnable());
Thread t2=new Thread(new MyRunnable());
t1.start();
t2.start();
//强制清除线程的等待状态,并会报异常:InterruptedException
t1.interrupt();
ReentrantLock类的方法
  • getHoldCount() 查询当前线程保持此锁的次数,也就是执行此线程执行lock方法的次数
  • getQueueLength()返回正等待获取此锁的线程估计数,比如启动10个线程,1个线程获得锁,此时返回的是9
  • getWaitQueueLength(Condition condition)返回等待与此锁相关的给定条件的线程估计数。比如10个线程,用同一个condition对象,并且此时这10个线程都执行了condition对象的await方法,那么此时执行此方法返回10
  • hasWaiters(Condition condition)查询是否有线程等待与此锁有关的给定条件(condition),对于指定contidion对象,有多少线程执行了condition.await方法
  • hasQueuedThread(Thread thread)查询给定线程是否等待获取此锁
  • hasQueuedThreads()是否有线程等待此锁
  • isFair()该锁是否公平锁
  • isHeldByCurrentThread() 当前线程是否保持锁锁定,线程的执行lock方法的前后分别是false和true
  • isLock()此锁是否有任意线程占用
  • lockInterruptibly()如果当前线程未被中断,获取锁
  • tryLock()尝试获得锁,仅在调用时锁未被线程占用,获得锁
  • tryLock(long timeout TimeUnit unit)如果锁在给定等待时间内没有被另一个线程保持,则获取该锁
tryLock和lock和lockInterruptibly的区别
  1. tryLock能获得锁就返回true,不能就立即返回false,tryLock(long timeout,TimeUnit unit),可以增加时间限制,如果超过该时间段还没获得锁,返回false
  2. lock能获得锁就返回true,不能的话一直等待获得锁
  3. lock和lockInterruptibly,如果两个线程分别执行这两个方法,但此时中断这两个线程,前者不会抛出异常,而后者会抛出异常
Condition类和Object类
  1. Condition类的awiat方法和Object类的wait方法等效
  2. Condition类的signal方法和Object类的notify方法等效
  3. Condition类的signalAll方法和Object类的notifyAll方法等效Lock的公平锁和非公平锁
  4. ReentrantLock类可以唤醒指定条件的线程,而object的唤醒是随机的
Lock的公平锁和非公平锁
Lock lock=new ReentrantLock(true);//公平锁
Lock lock=new ReentrantLock(false);//非公平锁
  • 公平锁指的是线程获取锁的顺序是按照加锁顺序来的,而非公平锁指的是抢锁机制,先lock的线程不一定先获得锁。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值