线程的同步机制 文章目录 1.什么是线程同步2.线程同步的实现1、同步方法2.同步代码块3.Lock锁4、synchronized与Lock的对比 1.什么是线程同步 线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作 那相对的线程异步处理就不用阻塞当前线程,而是允许后续操作,直至其他线程将处理完成,并回调此线程 2.线程同步的实现 不安全的例子(买票): 执行结果:
此时我们可以看到,票竟然被抢到了负数,这就是一个线程不安全的例子,当票只剩下一张时,一个线程到达了延时,此时还没有买票,因此票还有一张,第二个线程也来判断,发现票还有,于是也是在等待延迟,延迟完后,两个线程都买到了票,但票就只剩下一张,因此这就是一个没有任何同步机制的不安全案例 1、同步方法 synchronized方法控制对对象的访问,每个对象对应一把锁,每个synchronized方法都必须获得调用该方法的锁才能执行,否则会线程阻塞,方法一旦执行,就独占该锁,直到该方法返回才会释放锁,后面被阻塞的线程才能获得这把锁,继续执行 缺陷:将一个大的方法申明为synchronize会影响效率 执行结果:
每次线程调用buy()方法时,都要先获得一个锁,其他线程来的时候锁已经被占有了,因此只能进入阻塞状态,等待线程释放锁,其他线程才能继续这把锁继续执行 2.同步代码块 同步方法锁的是整个方法,而当这个方法里有些业务不需要锁就能执行时,锁的粒度过大会影响性能,因此可以加同步代码块 代码块中synchronized (Obj),需要获得一个对象 Obj 被称为同步监视器 Obj 可以是任何对象,但是推荐使用共享资源作为同步监视器 同步方法中无需指定同步监视器,因为同步方法的同步监视器就是this,就是这个对象本身,或者是class 同步监视器的执行过程 1、第一个线程访问,锁定同步监视器,执行其中代码 2、第二个线程访问,发现同步监视器被锁定,无法访问 3、第一个线程访问完毕,解锁同步监视器(释放锁) 4、第二个线程访问,发现没有锁,然后锁定并访问 执行结果是一样的 3.Lock锁 从JDK5.0开始,Java提供了强大的线程同步机制——通过显示定义同步锁对象来实现线程同步。同步锁使用Lock充当java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应鲜活的Lock对象ReentrantLock类实现了Lock,它拥有和synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显示加锁,释放锁 要要想使用Lock锁,得现有一个Lock对象,才能加锁解锁 执行结果:
注意:解锁的操作最好放在try/catch的finally中,这样不管有没有异常,它都会解锁,避免资源浪费等问题 4、synchronized与Lock的对比 Lock是显示锁,需要自己手动开启和关闭,synchronized是隐式锁,出了作用于自动释放,无需自己释放Lock只能锁代码块,synchronized可以锁代码块和方法使用Lock锁,JVM将花费更少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类) + 优先使用顺序: Lock > 同步代码快 > 同步方法
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/19197.html