[Java]—sychronized关键字

sychronized

    • 引入
    • 使用方法

昨天的面试里,还提到了关于锁的问题,这个问题在多线程的编程里需要特别注意,否则会产生数据不一致的情况,导致结果错误,也有可能会造成死锁。今天特意总结一下Java里sychronized的关键字的使用

引入

关于此关键字,我们首先要知道为什么需要这个关键字。我们可以想像一下,你去银行存钱,而正好又有其他人向你的账户里汇钱,如果,你存钱的时候,别人也正好在汇钱,而此时获取你银行卡里的金额可能是初始金额x,如果不论是你还是另外一个人获取到的都是x,并且在此基础上加上存入的金额,再改写总金额,那么必然会导致总金额错误的情况,这就相当于有两个不同的线程都在访问你的银行余额并对其进行操作,如果不进行一定的同步操作,则会因为线程推进的顺序产生意想不到的错误。所以,当采用多线程时,我们需要考虑是否需要对某些内容进行同步,保持它的一致性,避免出现运行错误。此时,我们就引进了sychronized。

使用方法

推荐博客:https://blog.csdn.net/qq_25302451/article/details/78764580
我的大部分理解都是通过这个博客来的。
sychronized有两种使用方法:对象锁、类锁。

  • 对象锁——sychronized

(1) 修饰方法

public synchronized void addMoney(){
     
    //函数体
 }

当我们用sychronized来修饰一个方法时,其实是获得了一个对象锁。而该对象就是我们用来调用这个方法的实例,例如语句:bankID1.addmoney(),那么当该线程运行到这一句时,若没有其他线程已经获取了该对象的对象锁,就可以在获得bankID1的对象锁后执行该方法。若已有其他线程获得了bankID1的对象锁,则该线程只能等待对象锁被释放。

(2) 修饰代码块

public void addMoney(){
     
	....
    synchronized (Bank bank1){
     //可传入我们自己指定的对象
        //代码
    }
    ....
}

其实,这两种不同的方式都是对应的对象锁,只不过如果用sychronized去修饰方法,它锁住的对象是固定,永远都是调用这个方法的那个对象。而当我们用sychronized来修饰代码块时,可以传入自己指定的对象,当然如果我们传入的是this指针,那么指代的也就是调用这个方法的那个对象。

  • 类锁——static sychronized
    (1)修饰方法
public static synchronized void addMoney(){
     
    //函数体
}

当我们将sychronized作用于一个static方法时,就变成了类锁,他锁住的是整个类,即这个类所有的实例都是用的同一把锁。

你可能感兴趣的:(Java,java,多线程)