java技术深入(一)——java多线程(五)——线程同步(一)

1、同步意义:同步存取,解决对共享数据(资源)的竞争引起的讹误。
2、同步方法:确保关键操作的原子性(不被干扰),即代码执行不被中断并且访问的数据不被污染。
3、java同步机制:锁机制、监视器机制。这两种本质都是确保操作的原子性,即防止关键代码块受到并发访问的干扰(执行过程和数据)。
4、锁机制的实现:锁机制只要靠synchronized来达到这一目的的。基于此关键字还可以使用ReentrantLock类来实现锁机制。synchronized关键字自动提供一种锁已经相关的条件,是一种显式的锁。java.util.concurrent框架下的ReentrantLock类则是基于synchronized的独立类,用这个类来实现代码块保护的基本结构是:
Lock myLock = new ReentrantLock();//定义锁
myLock.lock();//上锁
rty
{
    //临界区代码
}
finally//把解锁代码放在finally里是必要的,如果临界区代码抛出异常,所必须被释放!
{
    myLock.unlock();//解锁。注意:如果临界区代码出现异常而到达解锁这时进入临界区的对象可能处于受损状态。
}
这样的结构可以确保任意时刻最多只有一个线程进入上锁和解锁之间的代码块(即临界区)。当多于一个的线程试图进入临界区(执行临界区的代码)时将全部会被阻塞,进入阻塞队列。在前一个线程退出临界区并释放锁时,阻塞队列将会按照某种特定的算法(优先级优先算法,最长等待时间优先算法等等)挑选出一个线程激活。
5、锁是可重入的。即持有锁的线程可以嵌套重复持有相同的锁(这里的锁指的是锁对象,进入临界区执行代码的线程,在退出临界区之前可以再次嵌套进入临界区)。锁会维护一个计数器来跟踪这种嵌套调用,线程的上锁和解锁必须遵循栈规则。另外,基于这个道理,被同一个锁保护起来的不同代码段,不同段之间是可以相互调用的。
6、锁定义:ReentrantLock()  //定义普通可重入锁
                   ReentrantLock(boolean fair)  //定义公平可重入锁,这种锁偏爱等待时间最长的线程。但是会大大降低效率。

7、条件对象:确保原子性可能会造成线程死锁或者过长时间的忙等。条件对象就是解决这个问题。条件对象一般放置临界区里面,可以让已经持有锁(排他)的进程在不满足条件的情况下阻塞并释放锁,等待条件满足时再解除条件阻塞(但是未必可以激活线程)。
Lock myLock = new ReentrantLock();//定义锁
Condition myCondition;
myLock.lock();//上锁
rty
{
    //临界区代码
    myCondition=myLock.newCondition();//定义条件对象
    while(条件不满足)
    {
        myCondition.await();//当前线程放弃锁并阻塞(等待)。
    }//注意,即时条件对象停止了线程的等待(激活),这个等待条件也需要再检查一次以确保无误(signalAll()仅仅是通知正在等待的线        //程可能已经满足条件!)。

}
finally//把解锁代码放在finally里是必要的,如果临界区代码抛出异常,所必须被释放!
{
    myLock.unlock();//解锁。注意:如果临界区代码出现异常而到达解锁这时进入临界区的对象可能处于受损状态。
}
注意:在临界区外等待的线程和调用await等待的线程有本质不同。一旦一个线程调用await方法进入该条件对象的等待集,只有在另外一个线程调用同一个条件对象的signalAll()方法这个线程才会被解除条件阻塞,被解除条件阻塞的线程会重新尝试获取锁,一旦获取成功线程将从await()调用中返回并继续执行余下临界区的代码(而不是重进临界区)。
与signalAll方法类似的还有signal,它是随机解除等待集中的某一个线程。


 


 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值