<Java>多线程——Lock锁方式解决线程安全问题

Lock接口提供了与synchronized关键字类似的同步功能

synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁定的访问,但却强制所有锁定获取和释放均要出现在一个块结构中:当获取了多个锁定时,它们必须以相反的顺序释放,且必须在与所有锁定被获取时相同的词法范围内释放所有锁定。

虽然synchronized方法和语句的范围机制使得使用监视器锁定编程方便了很多,而且还帮助避免了很多涉及到锁定的常见编程错误,但有时也需要以更为灵活的方式使用锁定。例如,某些遍历并发访问的数据结果的算法要求使用 “hand-over-hand” 或 “chain locking”:获取节点 A 的锁定,然后再获取节点 B 的锁定,然后释放 A 并获取 C,然后释放 B 并获取 D,依此类推。Lock 接口的实现允许锁定在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁定,从而支持使用这种技术。

ReentrantLock构造方法

  • ReentrantLock():构建一个ReentrantLock的实例,这等同于使用 ReentrantLock(false)

  • ReentrantLock(boolean fair): 创建一个具有给定公平策略的 ReentrantLock
    参数:
    fair - 如果此锁定是公平的,则该参数为 true;否则为false

使用方式


Lock lock=new ReentrantLock();   //显式的获取锁
lock.lock();
try
{
	// access the resource protected by this lock
	//处理逻辑
}
finally
{
	lock.unlock();   //显式的释放锁
}


例题:多窗口售票问题

class lockThread implements Runnable
{
    private int tickets=100;
    //实例化Reentrantlock
    Lock lock=new ReentrantLock();  //默认false,非公平锁
    public void run()
    {
        while(true)
        {
            lock.lock();   //上锁
            try {
                if (tickets > 0) {
                    System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + (100 - tickets + 1));
                    tickets--;
                } else {
                    break;
                }
            }
            finally {
                lock.unlock();    //释放锁
            }
        }
    }
}

synchronized与Lock异同

相同:二者都可以解决线程安全问题

不同synchronized机制在执行完相应同步代码后,会自动释放同步监视器;Lock需要手动获得锁(lock()),手动释放锁(unlock()

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值