关于线程安全

由于多线程共享数据或资源,导致误读,脏读,造成错误,影响安全,故称多线程不安全。

实例:

        模拟三个窗口售票,票源为100张票,三个窗口同时出售。

        定义一个Runnable实现类

 

       在测试main中创建三个线程,共享RunableImp中数据。

 

打印结果如下:

 

其中出现了相同票号和票号为0和-1的错误数据。说明多线程共享数据并不安全。

成因分析:

       多线程共享CPU执行权,且并行运行,相互切换,造成脏读、误读。

 

显然,这种线程不安全在实际中是不能被接收的。

解决方案:

       一个线程访问共享数据的时候,无论是否失去了CPU的执行权,让其他线程只能等待当前线程释放数据后,其他线程才能使用。

        解决思想: 让需要同步的代码只能让一个线程执行

         方法一:同步代码块。     synchronized关键字可以用于方法中的某个区块中,表示只对这个区块的资源进行互斥访问。

        格式:

                     synchronized(同步锁){

                                // 需要同步操作的代码。

                     }

         实例: 以之前案例说明,修改RunnableImp如下:

 

         运行结果:

 

 

       资源数值正常递减,未出现错误数据。

         方法二: 同步方法  使用synchronized关键字修饰方法

        格式:

                     public synchronized(同步锁) void method(){

                                // 需要同步操作的代码。

                     }

            同步方法的锁对象就是实现类对象,也就是this.

        实例如下图:

 

     此时:锁对象是this,即类实例对象。

     除此之外,还可以使用静态同步方法,此时锁对象是类的class属性 -->class文件对象。

 

方法三:锁机制

       主要为使用Lock接口锁,其实现类主要使用Reentrantlock。

       使用步骤:

       1. 在成员位置创建一个Reentrantlock对象。

       2. 在可能出现安全问题的代码前调用lock接口中的lock获取锁。

       3. 在可能出现安全问题的代码后调用lock接口中的unlock释放锁。

      实例:

 

打印结果如下:

 

 

注意使用lock时的代码格式,将lock.unlock 放入finally中,无论代码是否报错,都释放锁,与释放IO流同理

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值