前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用不用 synchronized 的区别?

用不用 synchronized 的区别?

作者头像
LieBrother
发布2020-05-25 10:49:10
3340
发布2020-05-25 10:49:10
举报
文章被收录于专栏:LieBrother

今天一起来认识认识 「synchronized」 这个一面试就会被提到的关键字。这一篇不会讲太多理论,主要先熟悉熟悉一下最简单的用法。只讨论一个问题:「方法没用 synchronized 和用了 synchronized 有什么区别?」

首先我们的理论基础是 「synchronized」 关键字是用在多线程并发的场景,所以接下来的测试代码都会模拟多线程并发的情况。我们直接通过代码来给大家讲讲加没加 synchronized 的区别。

1. 方法没加 synchronized 关键字

我们先写一个普通到不能再普通的代码,就是一个实例方法,在多线程并发的情况下执行同一个方法。如下所示。

代码语言:javascript
复制
public class NoSynchronizedTest {

    public static void main(String[] args) {
        NoSynchronizedTest noSynchronizedTest = new NoSynchronizedTest();
        for (int i = 0; i < 5; i ++) {
            Thread thread = new Thread(() -> {
                noSynchronizedTest.testNoSynchronizedMethod();
            });
            thread.start();
        }
    }

    public void testNoSynchronizedMethod() {
        System.out.println("testNoSynchronizedMethod-start-" + Thread.currentThread().getName());
        System.out.println("testNoSynchronizedMethod-end-" + Thread.currentThread().getName());
    }

}

运行结果:

我们可以发现如下结论:

  1. 在单线程中,执行顺序是有保证的,也就是每个 start 都优先于 end。
  2. 在多线程中,线程之间的 start 和 end 是没有先后顺序的,先进入方法的线程不一定先执行完方法。我们看运行结果的红色框,5 个线程只有 Thread-2 是完整的执行完方法,没有其他线程乱入的。

2. 方法加 synchronized 关键字

我们对上面的代码稍加修改,在方法上加 「synchronized」 修饰,并且在两种情况下执行代码。

5 个线程只有一个 synchronizedTest 对象。
代码语言:javascript
复制
public class SynchronizedTest {

    public static void main(String[] args) {
        SynchronizedTest synchronizedTest = new SynchronizedTest();
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(() -> {
                synchronizedTest.testSynchronizedMethod();
            });
            thread.start();
        }
    }

    public synchronized void testSynchronizedMethod() {
        System.out.println("testSynchronizedMethod-start-" + Thread.currentThread().getName());
        System.out.println("testSynchronizedMethod-end-" + Thread.currentThread().getName());
    }
}

运行结果:

5 个线程中,每个线程有各自的 synchronizedTest 对象。
代码语言:javascript
复制
public class SynchronizedTest {

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            SynchronizedTest synchronizedTest = new SynchronizedTest();
            Thread thread = new Thread(() -> {
                synchronizedTest.testSynchronizedMethod();
            });
            thread.start();
        }
    }

    public synchronized void testSynchronizedMethod() {
        System.out.println("testSynchronizedMethod-start-" + Thread.currentThread().getName());
        System.out.println("testSynchronizedMethod-end-" + Thread.currentThread().getName());
    }
}

运行结果:

我们可以发现如下结论:

  1. 当 5 个线程中只有一个对象时,5 个线程之间的执行顺序是串行的,互不影响,线程0进入方法后,其他线程就无法再进入方法了,得等待线程0执行完后,其他线程才能进入,并且一次只能有1个线程进入。
  2. 每个线程一个对象时,就不会出现排队的场景,各个线程互不影响,相当于每个线程都有各自的资源,没有互相竞争的关系。

由此,我们可以得出什么呢?「synchronized」 关键字就是「悲观锁」的具体实现,在多线程并发竞争同一资源时,实现同一时刻只有一个线程能操作资源。

这篇文章是了解 「synchronized」 最最最皮毛的知识,对 「synchronized」 熟悉的朋友可以当做是回顾知识点,不熟悉的朋友可以当做是入门,后面会继续深挖知识点。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LieBrother 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 方法没加 synchronized 关键字
  • 2. 方法加 synchronized 关键字
    • 5 个线程只有一个 synchronizedTest 对象。
      • 5 个线程中,每个线程有各自的 synchronizedTest 对象。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档