1 多线程安全问题
1.1 问题引入
(1)多个线程执行的不确定性引起执行结果的不稳定。
(2)多个线程对数据的共享,会造成操作的不完整性,会破坏数据。
────────────────────────────────────────────────────────────
1.2 问题的原因
(1)当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。
(2)例如电影票售票:<独行月球> 100 张票,线上的销售渠道可以有许多:美团、猫眼、淘票票等。
三个销售渠道可以认为是三个销售线程, 100 张票是共享资源,但100 张票内不可以销售重复的票。 |
────────────────────────────────────────────────────────────
1.3 解决办法
(1)对操作共享数据的语句,每次只能让一个线程执行,在执行过程中,其他线程不可以参与执行。
(2)Java 对于多线程的安全问题提供了专业的解决方式:同步机制
────────────────────────────────────────────────────────────
2. 同步机制
2.1 同步锁机制
(1)Java 对于多线程的安全问题提供了专业的解决方式:同步机制
(2)对于并发工作,需要某种方式来防止两个任务访问相同的资源(共享资源竞争)。 防止这种冲突的方法就是当资源被一个任务使用时,在其上加锁。第一个访问某项资源的任务必须锁定这项资源,使其他任务在其被解锁之前,就无法访问它了,而在其被解锁之时,另一个任务就可以锁定并使用它了。
(3)线程同步代码,限制有且只允许一个线程对象进入代码执行,线程任务一旦被抢占,锁对象【落锁】,其他线程无法进入,线程任务执行完毕,锁对象【开锁】,所有线程可以进入任务抢占操作。
────────────────────────────────────────────────────────────
2.2 同步代码块
(1)需要被同步的代码:操作共享数据的代码
(2)共享数据:多个线程共同操作的变量
(3)同步监视器:需要自己指定,很多时候也是指定为 this 或类名.class。
synchronized (同步监视器){
// 需要被同步的代码;
}
────────────────────────────────────────────────────────────
2.3 同步方法
(1)使用 synchronized 修饰方法,表示整个方法为同步方法。
(2)同步方法仍然涉及到同步监视器,只是不需要显式的声明。
(3