Java基础361问第15问——线程安全的方法
创始人
2025-05-31 09:28:38
0

文章目录

  • 什么是数据不一致问题?
  • 怎样才能保证数据一致?---> 要改谁就锁谁
  • 1 synchronized 关键字 ⭐️⭐️⭐️⭐️⭐️
    • 1.1 普通方法
    • 1.2 静态方法
    • 1.3 代码块 (推荐使用,颗粒度可控)
  • 2 使用ReentrantLock

什么是数据不一致问题?

提到线程安全想必大家并不陌生,但是为什么真正项目中遇到多线程问题的时候却很棘手? 很大一部分原因是我们只学理论走马观花看了几篇博客背了几个面试点就以为自己掌握了,Talk is Cheap, Show me the code! 因此这篇文章我会结合具体的代码介绍几种线程安全的方法和注意事项,希望能给你一个清晰地印象。

我们以火车售票场景为例,假如有两个窗口同时卖票,代码如下

public class Test {static class SellTickets implements Runnable {private int tickets = 10;@Overridepublic void run() {while (tickets > 0) {String name = Thread.currentThread().getName();System.out.println(name + "售票成功! 还剩 " + (--tickets) + " 张票~");delay1s();}}private void delay1s() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {SellTickets sellTickets = new SellTickets();Thread one = new Thread(sellTickets, "1号窗口");Thread two = new Thread(sellTickets, "2号窗口");one.start();two.start();}}

这段代码没有做线程安全的处理, 我们看下运行结果 (如果你运行的结果没有异常可以多试几次)

1号窗口售票成功! 还剩 9 张票~     
2号窗口售票成功! 还剩 8 张票~
2号窗口售票成功! 还剩 7 张票~   
1号窗口售票成功! 还剩 7 张票~    // error 数据错误 只剩6张票但是说剩7张
1号窗口售票成功! 还剩 6 张票~
2号窗口售票成功! 还剩 6 张票~    // error 数据错误 
2号窗口售票成功! 还剩 4 张票~
1号窗口售票成功! 还剩 5 张票~
2号窗口售票成功! 还剩 3 张票~
1号窗口售票成功! 还剩 2 张票~
2号窗口售票成功! 还剩 1 张票~
1号窗口售票成功! 还剩 0 张票~

这就是多线程带来的数据不一致问题: A线程对共享变量的修改没有同步到B线程,B线程读取到错误的变量值

怎样才能保证数据一致?—> 要改谁就锁谁

1 synchronized 关键字 ⭐️⭐️⭐️⭐️⭐️

 synchronized (this){System.out.println(name + "售票成功! 还剩 " + (--tickets) + " 张票~");}

synchronized 可用于修饰普通方法、静态方法和代码块

1.1 普通方法


class A {// 同步方法public synchronized void method1() {}// 非同步方法public  void method2() {}
}

当 synchronized 修饰普通方法时,被修饰的方法被称为同步方法,其作用范围是整个方法,作用的对象是调用这个方法的对象。

  • 假设目前有两个线程: 1和2同时执行 A0对象的method1()方法,那么就会出现竞争, 先抢到锁的线程1可以执行此方法,线程2进入等待直到线程1释放锁才可以执行method1()方法
  • 假设目前有两个线程: 1和2同时执行 A0对象的method2()方法,不存在竞争,可以同时执行
  • 假设目前有两个线程: 1执行 A0对象的method1()方法, 2 执行A1对象的method1()方法,不存在竞争,可以同时执行

1.2 静态方法

class B {public static synchronized void method1() {}public static void method2() {}
}

当 synchronized 修饰静态方法时,其作用范围是整个程序,这个锁对于所有调用这个锁的对象都是互斥的。

  • 假设目前有两个线程: 1和2同时执行 B0对象的method1()方法,那么就会出现竞争, 先抢到锁的线程1可以执行此方法,没有抢到锁的线程2需要等待线程1释放锁才可以执行 (和普通方法特性相同)
  • 假设目前有两个线程: 1执行 B0对象的method1()方法, 2 执行B1对象的method1()方法,存在竞争, 先拿到锁的线程先执行 (这点特殊, 针对所有的对象)
  • 假设目前有两个线程: 1和2同时执行 B0对象的method2()方法,不存在竞争,可以同时执行 (和普通方法特性相同)

1.3 代码块 (推荐使用,颗粒度可控)

class C {public static void method2() {// 加锁某个类synchronized (SynchronizedUsage.class) {// ......}// 加锁当前类对象synchronized (this) {// ......}// 加锁某个对象,如果害怕多线程修改这个对象可以锁住这个对象synchronized (object) {object = xxxx}}}

代码块加锁这种方式可以放两种元素: 对象 和 class, 对象的话作用和普通方法类似,class的话作用和静态方法类似。

2 使用ReentrantLock

ReentrantLock 是 Java 提供的一个可重入锁,它和 synchronized 类似,但是更加灵活,可以支持多个条件变量和公平锁等特性

需要注意的是: lock 和 unlock需要配合使用,如果不调用unlock会造成死锁,一般会结合try finally使用

        private int tickets = 10;ReentrantLock lock = new ReentrantLock();@Overridepublic void run() {while (tickets > 0) {String name = Thread.currentThread().getName();try {lock.lock();System.out.println(name + "售票成功! 还剩 " + (--tickets) + " 张票~");} finally {lock.unlock();}delay1s();}}

虽然也有一些其他的方法实现线程安全,但是这两个方法应该可以解决99%以上的问题,大家可以看完自己敲一下理解一下。

相关内容

热门资讯

电视安卓系统哪个品牌好,哪家品... 你有没有想过,家里的电视是不是该升级换代了呢?现在市面上电视品牌琳琅满目,各种操作系统也是让人眼花缭...
安卓会员管理系统怎么用,提升服... 你有没有想过,手机里那些你爱不释手的APP,背后其实有个强大的会员管理系统在默默支持呢?没错,就是那...
安卓系统软件使用技巧,解锁软件... 你有没有发现,用安卓手机的时候,总有一些小技巧能让你玩得更溜?别小看了这些小细节,它们可是能让你的手...
安卓系统提示音替换 你知道吗?手机里那个时不时响起的提示音,有时候真的能让人心情大好,有时候又让人抓狂不已。今天,就让我...
安卓开机不了系统更新 手机突然开不了机,系统更新还卡在那里,这可真是让人头疼的问题啊!你是不是也遇到了这种情况?别急,今天...
安卓系统中微信视频,安卓系统下... 你有没有发现,现在用手机聊天,视频通话简直成了标配!尤其是咱们安卓系统的小伙伴们,微信视频功能更是用...
安卓系统是服务器,服务器端的智... 你知道吗?在科技的世界里,安卓系统可是个超级明星呢!它不仅仅是个手机操作系统,竟然还能成为服务器的得...
pc电脑安卓系统下载软件,轻松... 你有没有想过,你的PC电脑上安装了安卓系统,是不是瞬间觉得世界都大不一样了呢?没错,就是那种“一机在...
电影院购票系统安卓,便捷观影新... 你有没有想过,在繁忙的生活中,一部好电影就像是一剂强心针,能瞬间让你放松心情?而我今天要和你分享的,...
安卓系统可以写程序? 你有没有想过,安卓系统竟然也能写程序呢?没错,你没听错!这个我们日常使用的智能手机操作系统,竟然有着...
安卓系统架构书籍推荐,权威书籍... 你有没有想过,想要深入了解安卓系统架构,却不知道从何下手?别急,今天我就要给你推荐几本超级实用的书籍...
安卓系统看到的炸弹,技术解析与... 安卓系统看到的炸弹——揭秘手机中的隐形威胁在数字化时代,智能手机已经成为我们生活中不可或缺的一部分。...
鸿蒙系统有安卓文件,畅享多平台... 你知道吗?最近在科技圈里,有个大新闻可是闹得沸沸扬扬的,那就是鸿蒙系统竟然有了安卓文件!是不是觉得有...
宝马安卓车机系统切换,驾驭未来... 你有没有发现,现在的汽车越来越智能了?尤其是那些豪华品牌,比如宝马,它们的内饰里那个大屏幕,简直就像...
p30退回安卓系统 你有没有听说最近P30的用户们都在忙活一件大事?没错,就是他们的手机要退回安卓系统啦!这可不是一个简...
oppoa57安卓原生系统,原... 你有没有发现,最近OPPO A57这款手机在安卓原生系统上的表现真是让人眼前一亮呢?今天,就让我带你...
安卓系统输入法联想,安卓系统输... 你有没有发现,手机上的输入法真的是个神奇的小助手呢?尤其是安卓系统的输入法,简直就是智能生活的点睛之...
怎么进入安卓刷机系统,安卓刷机... 亲爱的手机控们,你是否曾对安卓手机的刷机系统充满好奇?想要解锁手机潜能,体验全新的系统魅力?别急,今...
安卓系统程序有病毒 你知道吗?在这个数字化时代,手机已经成了我们生活中不可或缺的好伙伴。但是,你知道吗?即使是安卓系统,...
奥迪中控安卓系统下载,畅享智能... 你有没有发现,现在汽车的中控系统越来越智能了?尤其是奥迪这种豪华品牌,他们的中控系统简直就是科技与艺...