java的监视器锁synchronized

关于这个synchronized锁,过去是一直避免使用的,说他是重量级锁,锁的性能差,远不如ReentrantLock

 

但是后来看了java并发编程实战,里面提到随着java版本的升级,内置锁synchronized的性能已经得到了很大

的提升,而且他作为内置锁,对内存的消耗更小一点(看大佬这么说,其实我也不知道为啥内存更小额,等我看完jvm和java核心技术再回来解释)。

 

用法很简单,可以分三种情况:

synchronized加在普通方法上:对对象实例加内置锁

synchronized加在静态方法上:对Class对象加内置锁

synchronized加在代码块上:对参数加内置锁

 

下面针对1,2两种情况做一个区分的验证。

 

public static void main(String[] args) throws InterruptedException {
    //开启四个线程
    new Thread(() -> new Load().test()).start();
    new Thread(() -> new Load().test()).start();
    new Thread(() -> new Load().test()).start();
    new Thread(() -> new Load().test()).start();

    //休眠一会,主线程等等其他线程,这个值看情况调整哈。
    Thread.sleep(1000);
    System.out.println(Count.i);

}
public void test() {
    for (int t = 0; t < 5000; t++) {
        Count.i++;
    }
}

 

public class Count {
    public static int i=0;


}

执行结果为17565,这个结果是随机的,不是20000肯定是说明它线程不安全

接下来对test方法synchronized字段

public synchronized void test() {
    for (int t = 0; t < 5000; t++) {
        Count.i++;
    }
}

结果是13996,还是线程不安全的,这是为啥呢,就是因为四个线程里执行方法时new 了一个对象实例去执行的

而对于普通方法synchronized字段锁的是实例,不同实例意味着他们之间没有冲突,同一个实例才冲突

下面将线程里的方法改为同一个对象测试

public static void main(String[] args) throws InterruptedException {
    //开启四个线程
    Load load = new Load();
    new Thread(() ->load.test()).start();
    new Thread(() -> load.test()).start();
    new Thread(() -> load.test()).start();
    new Thread(() -> load.test()).start();

    //休眠一会,主线程等等其他线程。
    Thread.sleep(1000);
    System.out.println(Count.i);

}

这时答案就稳定了,只有20000,这种用法就是线程安全的了,如果在方法上加入static成为静态方法,那么只要是Load类的实例都会冲突

我把main里的方法改回去,把test方法上加上static,再次测试

 

new Thread(() -> new Load().test()).start();
new Thread(() -> new Load().test()).start();
new Thread(() -> new Load().test()).start();
new Thread(() -> new Load().test()).start();
public static synchronized void test() {
    for (int t = 0; t < 5000; t++) {
        Count.i++;
    }
}

 

结果也是稳定的20000,也是线程安全的

 

 

 

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值