Java Synchronized 的用法

2019-07-11  本文已影响0人  oO白眉大虾Oo

Synchronized 是由Java SDK自带的轻量级的同步锁,可以非常方便的解决在多线程环境下的资源竞争问题,本篇主要讲述相关的用法以及注意点,以便能更好的使用同步锁。

使代码具有 原子性(atomicity)和 可见性(visibility),支持锁方法、锁对象、锁字符串

锁方法时,锁的是类的this变量,区分实例方法和静态方法的区别

锁对象时,锁的是对象的this变量

锁字符串时,锁的是字符串,这里要注意锁的是不是同一个字符串,如果是动态字符串它不是在String Pool中存储的,需要用intern().

特点

先看一个反例,对余额进行1000次累加后,最后的输出结果可能是999

public class Bank {

    private Double money = 0D;

    public void add(Double money) {
        this.money = this.money + money;
    }
    
    @Test
    public void synchronizedMethod() throws InterruptedException {
        private Bank bank = new Bank();
        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {

                public void run() {
                    bank.add(1d);
                }

            }).start();
        }

        Thread.sleep(2000);
        System.out.println(bank.getMoney());
    }
    ...
}

为了解决这个问题,可以应用上面提到的三种方式

第一种 锁方法

public synchronized void add(Double money) {
    this.money = this.money + money;
}

第二种 锁对象

public void add(Double money) {
    synchronized (this) {
        this.money = this.money + money;    
    }       
}

第三种 锁字符串

public void add(Double money) {
    synchronized ("Lock") {
        this.money = this.money + money;    
    }       
}
// 锁字符串,要特别注意,如果是new String()是存储在堆中的,而不是在常量池,需要用intern().
上一篇 下一篇

猜你喜欢

热点阅读