目录
线程的安全问题
线程的安全问题(Thread Safety Issue)是指在多线程编程中,多个线程同时访问共享资源时,可能会引发的数据不一致、死锁、竞争条件等问题。
示例
需求
代码实现
出现的问题
会卖重复的票
有超出范围的票
问题分析
线程在执行时,具有随机性,cpu的执行权有可能随时会被其他的线程抢走,比如1号线程在打印之前,cpu的执行权被2号线程抢走,2号线程执行ticket++,使ticket为2,而2号线程在打印之前,cpu的执行器又被3号线程抢走,3号线程执行ticket++,使ticket为3。此时1号线程拿到cpu的执行器,继续执行代码,打印ticket,此时ticket为3;2号线程又拿到cpu的执行权,继续执行代码,打印ticket,此时ticket为3,3号线程又拿到cpu的执行权,继续执行代码,打印ticket,此时ticket为3。这就是卖出重复票的原因。
票超出范围的原因跟上面同理,比如1号线程在打印之前,cpu的执行权被2号线程抢走,2号线程执行ticket++,使ticket为101,而2号线程在打印之前,cpu的执行器又被3号线程抢走,3号线程执行ticket++,使ticket为102。此时1号线程拿到cpu的执行器,继续执行代码,打印ticket,此时ticket为102;2号线程又拿到cpu的执行权,继续执行代码,打印ticket,此时ticket为102,3号线程又拿到cpu的执行权,继续执行代码,打印ticket,此时ticket为102。
解决方案
同步代码块
在多线程编程中,同步代码块(Synchronized Block)是一种用于控制线程间访问共享资源的机制,确保多个线程不会同时进入一个关键部分或临界区(Critical Section),从而避免竞态条件(Race Condition)和数据不一致的问题。
打个比喻:把两个线程看成两个人,把操作共享数据的代码看成厕所,一个人进去蹲坑,那厕所自然会锁起来,不让另一个人进,只有当蹲坑的拉完之后(操作共享数据的代码执行完毕),厕所门开了,另一个人才有机会去抢夺厕所,但拉完的人可能没拉干净,他也有机会再次抢夺厕所。
代码示例
结果
不再出现重复的票和超出的票