初始线程安全问题

java wang 4年前 (2020-07-02) 517次浏览 0个评论 扫描二维码

为什么会有线程安全???

例如生活中抢购 买票问题,当你查询到有剩余车票时,只要你能够进入支付界面时候你肯定会买到这张票,因为这张票或者说资源已经被你锁定了,只要你不取消或者说是释放资源,其他人是无法买到这张票的,

那问题又来了,线程安全为嘛又扯到锁上面来了?

其实线程安全是用锁实现的,下面就介绍几种锁来实现线程安全。

1 synchronized 

用于修饰方法

public synchronized void getTicket()

优点:实现线程安全,资源只能被当前线程访问

缺点:线程串行化,效率低,只能等前一个线程完全走完之后,下一个线程才能进入,如上厕所这件事情,在别人上厕所时候起码你可以拿纸在外面等,不至于非要等别人上完厕所后,你再去拿纸。

所以 synchronized 衍生到 在方法内部执行

System.out.println(Thread.currentThread().getName()+” : 拿纸…”);
synchronized (this) {
System.out.println(Thread.currentThread().getName()+” : 上厕所…”);
System.out.println(Thread.currentThread().getName()+” : 出厕所”);
}
System.out.println(Thread.currentThread().getName()+” : 上完厕所,真舒服,洗个手 … end”);

衍生到内部之后,锁定的内容就是上厕所和出厕所,其他流程就不用排队。

然而衍生到方法内部,还有另一种加锁方式可以实现线程安全。

2 ReentrantLock lock对象

System.out.println(Thread.currentThread().getName() + " : 拿纸...");
    lock.lock();
    try {
        System.out.println(Thread.currentThread().getName() + " : 上厕所...");
        System.out.println(Thread.currentThread().getName() + " : 出厕所");
        System.out.println(Thread.currentThread().getName() + " : 上完厕所,真舒服,洗个手 ... end");
    } finally {
        // 3.使用Lock对象的unlock方法解锁
        lock.unlock();

跟 synchronized 相比需要主动加锁和释放。

注意:可把解锁的unlock方法的调用放在finally{}代码块中,保证一定能解锁

提醒:在同步的时候,其他代码都可以多个线程同时执行!只是被同步的代码不能同时执行!

那什么时候用lock 什么时候用 synchronized ??

在并发量比较小的情况下,使用synchronized是个不错的选择,但是在并发量比较高的情况下,其性能下降很严重,此时Lock是个不错的方案。

喜欢 (0)
[支付宝扫码,感谢支持]
分享 (0)
关于作者:

您必须 登录 才能发表评论!