美文网首页
Java Synchronized 的用法

Java Synchronized 的用法

作者: oO白眉大虾Oo | 来源:发表于2019-07-11 22:45 被阅读0次

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().

相关文章

网友评论

      本文标题:Java Synchronized 的用法

      本文链接:https://www.haomeiwen.com/subject/dkojkctx.html