毕向东讲解(摘)—6.多线程安全问题(同步函数)

本文探讨了在多线程环境下如何确保银行存款操作的线程安全性,通过使用同步函数来避免竞态条件,保证数据一致性。介绍了同步函数的原理及其实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package day6;

/**

 * 需求:

 * 现在有一个bank

 * 有两个cus往银行中存钱

 * 实现银行中金额的增加

 *

 * @author mzy

 *

 * 同步函数

 */

publicclassTest{

    publicstaticvoidmain(String[]args){

       Cuscus=newCus();

       Threadt=newThread(cus);

       Threadt1=newThread(cus);

       t.start();

       t1.start();

    }

}

/**

 * 因为bank中的add方法被cus多次调用,且为两位cus构成了多线程

 * 如果不给add加锁的话,就会导致线程不安全出错

 *

 * @author mzy

 *

 */

classBank{

    privateintsum;

    Objecto=newObject();

    publicsynchronizedvoidadd(intn){

       sum+=n;

       try{

           Thread.sleep(10);

       }catch(Exceptione){

          

       }

       System.out.println("sum = "+sum);

    }

}

 

 

classCusimplements Runnable{

    privateBankb=newBank();

    publicvoidrun(){

       for(inti=0;i<3;i++){

           b.add(100);

       }

    }

}

 

这里也就延续了同步代码块的问题,这里银行算账:如果不将run中的add方法抽离出来的话,为了保证线程安全,通过之前的内容,那么我们只有两种解决方法:

1. 将add所在的区域写成同步代码块的形式;(可以考虑,但是不能保证类的功能的单一性)

2. 将整个run方法都用synchronized修饰,这样run方法就变成了同步函数了,这样是很不合理的,纵使前面两个线程都开启了,但是其实自始至终,只有最开始进入的线程在执行。

所以这里最合理的方法就是使用同步函数的方式,将add抽离出来。

 

但是这里就有一个问题,因为最开始我们引入的时候,说明了同步是需要锁的,而且多个线程使用的必须是同一个锁,但是同步函数的调用的时候我我们只看见了传入的形参,并未看见传入的对象锁,这里需要说明的是同步函数的锁,是当前对象,我们都知道在调用对象内的方法时当前对象的this一般我们都会省略,除非变量名含糊不清时才会或者构造方法之间的互相调用时才会使用this关键字,其实在同步函数中的锁就是被我们省略的当前的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值