【多线程核心技术】---Lock的使用

一:ReentrantLock类

    ReentrantLock类可以实现线程间同步互斥,嗅探锁定,多路分支通知等功能。

    调用ReentrantLock对象的Lock()方法获取锁,调用UnLock()方法释放锁。

使用Condition实现等待/通知:

    使用Condition具有良好的灵活性,实现多路通知功能,也就是在一个Lock对象里面创建多个Condition(即对象监视器)实例,线程对象可以注册在指定的Condition中,从而有选择的进行线程通知,在调度线程上更加灵活。

    而synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有的线程都注册在它一个对象的身上。线程开始notifyAll()时,需要通知所有的WAITING线程,没有选择权,会出现效率问题。

    private ReentrantLock lock = new  ReentrantLock( );

    private Condition condition = lock.newCondition( );

    先调用Lock.lock()代码获得同步监视器,然后再调用condition.await( ).使当前执行任务的线程进入等待WAITING状态。

   try-catch-finally语句中 condition.await( )方法放在代码出口(及try代码块的最后一行),在finally代码块中Lock.UnLock( )。


    service.signalAll( )唤醒所有线程。---》可指定对象

    公平锁和非公平锁

    公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即先来先得的FIFO先进先出顺序。结果有序。

    非公平锁就是一种获取锁的抢占机制,是随机获得锁的,和公平锁不一样的是先来的不一定先得到锁,这种方式可能造成某些线程一直得不到锁,结果是不公平的。结果无序。

    方法getHoldCount(),getQueueLength()和getWaitQueueLength()

    1)方法getHoldCount()的作用是查询当前线程保持此锁定的个数,也就是调用Lock()方法的次数

    2)方法getQueueLength()的作用是返回正等待获取此锁的线程估计数。等待Lock释放的线程个数。

    3)方法getWaitQueueLength()的作用是返回等待此锁定相关的给定条件Condition的线程估计数。

    方法hasQueuedThread(),hasQueuedThread()和hasWaiters()

    1)Boolean hasQueuedThread()的作用是查询是否有线程正在等待获取此锁定。

    2)Boolean hasWaiters()的作用是查询是否有线程正在等待获取此锁定有关的condition条件。

    方法isFair(),isHeldByCurrentThread()和isLocked()

    1)Boolean isFair()判断是否为公平锁。在默认情况下,ReentrantLock类使用的是非公平锁。

    2)Boolean isHeldByCurrentThread()的作用是查询当前线程是否保持此锁定。

    3)Boolean isLocked()的作用是查询此锁定是否由任意线程保持。

    方法LockInterruptibly(),tryLock()和tryLock(Long  timeout ,TimeUnit  unit)

    1)方法void  LockInterruptibly()的作用是:如果当前线程未被中断,则获取锁定,如果已经中断则出现异常。

        lock.interrupt(  )线程中断后,Lock()不出现异常,正常执行。

        lock.Lockinterruptibly(  )线程中断后,Lock()报异常,停止执行。

    2)方法Boolean  tryLock()的作用是:仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定。

    3)方法Boolean  tryLockLong  timeout ,TimeUnit  unit)的作用是:如果在锁定给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定。

      方法awaitUninterruptibly()的使用

        await出现异常,awaitUninterruptibly正常运行无异常。

      方法awaitUntil()的使用

      指定时间唤醒,但在是等待时间内,可被其他线程提前唤醒。

     使用Condition实现顺序执行

    使用CondiTion对象可以对线程执行的业务进行排序规划。

二:ReentrantReadWriteLock类

   ReentrantLock类具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()方法后面的任务。保证了实例变量的线程安全性。
   ReentrantReadWriteLock读写锁

    1)一个是读操作相关的锁,也成为共享锁,

    2)另一个是写操作的锁,也叫排它锁。

    多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥。多个Thread可以同时进行读取操作,但是同一时刻只允许一个Thread进行写入操作。 

     使用写锁代码Lock.readLock( ),允许多个线程同时执行Lock()方法后面的代码。   

    使用写锁代码Lock.writeLock( )的效果就是同一时间只允许一个线程执行Lock()方法后面的代码。


定时器Timer的使用

    Timer的主要作用就是设置计划任务,但封装的类是TimerTask类,执行计划任务的代码放入TimerTask的子类中,Timer是一个抽象类。

    方法schedule(TimerTask    task,Date    time)该方法的作用是在指定的日期执行一次某一任务。

    1)执行任务的时间晚于当前时间:在未来执行

    创建一个Timer就是启动一个新的线程,这个新启动的线程并不是守护线程,它不会执行完就关闭,需要将创建Timer的线程改为守护线程。new Timer(true);

    2)计划时间早当前时间:提前运行

    3)多个TimerTask任务执行:顺序执行

    方法schedule(TimerTask    task,Date    firstTime    long    period)该方法的作用是在指定的日期之后,按指定的间隔周期性地无限循环地执行某一任务。

    1)执行任务的时间晚于当前时间:在未来执行

    2)计划时间早当前时间:提前运行

    3)任务执行时间被延时:任务延时但还是一个一个执行(即不能保证执行时间与预期时间一致)

    TimerTask类的cancel()方法

    TimerTask类中的cancel()方法的作用是将自身从任务队列中清除,其他任务不收影响。

    Timer类的cancel()方法

    和TimerTask类中的cancel()方法清除自身不同,Timer类中的cancel()方法的作用是将任务队列中的全部任务清空,并且进程任务被销毁。

    注意:Timer类中的cancel()方法的有时并不一定会停止执行任务计划,而会正常执行。这是因为Timer类中的cancel()方法有时并没有争抢到queue锁,所以其他任务还会继续正常执行。

    方法schedule(TimerTask    task,long    period)以执行当前方法的时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask任务。

    方法schedule(TimerTask    task,long    delay,long    period)以执行当前方法的时间为参考时间,在此时间基础上延迟指定的毫秒数,再以某一间隔时间无限次数地执行一次某一任务。

    方法scheduleAtFixedRate(TimerTask    task,Date    firstTime    long    period


相同点:

1、方法schedule 和方法 scheduleAtFixedRate 都会按顺序执行,所以不用考虑非线程安全的情况。

2、方法schedule 和方法 scheduleAtFixedRate 如果执行任务的时间没有被延迟,那么下一次任务的执行时间参考的是上一次的任务的"开始"时的时间来计算的。

3、方法schedule 和方法 scheduleAtFixedRate 如果执行任务的时间被延迟了,那么下一次任务的执行时间参考的是上一次任务"结束"时的时间来计算。


    1)执行schedule方法任务不延时:则下一次执行任务的时间是上一次任务的开始时间加上delay时间。

    2)执行schedule方法任务延时:则下一次执行任务的时间是上一次任务“结束”时的开始时间为参考来计算。

    3)schedule方法不具有追赶执行性

    1)执行scheduleAtFixedRate方法任务不延时:则下一次执行任务的时间是上一次任务的开始时间加上delay时间。

    2)执行scheduleAtFixedRate方法任务延时:则下一次执行任务的时间以上一次任务“结束”时的时间为参考来计算。

    3)scheduleAtFixedRate方法具有追赶执行性

        就是如果任务 在周期性运行过程中被打断了,scheduleAtFixedRate 会尝试把之前落下的任务补上运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值