对于synchronized你了解多少?

一、聊一聊 同步与异步

同步:执行每一行代码时,都要等它执行完毕或者得到它的返回之后再执行它的下一行代码。通俗来讲就是稳稳地串行,绝对不会制造并行情况!

异步:执行每一行代码时,不必立刻得到它执行的结果而是在执行它的同时去执行后续的代码,是会出现并行情况的!

这里说一下并行并发:举个例子,在一个单核的CPU中执行的进程是不可能出现并行状态的,只可能出现并发,并发是指由于“优先级”变化或者“时间片”用完抑或其他的情况导致的两个或多个进程交替执行的情况,它立足于特定的作业调度算法以及寄存器与程序计数器(中断不可或缺的条件)。并行是指在多核CPU中,两个或多个进程同时运行的情况。

那么再来看看同步和异步的理解:

再举个例子:假设你要从北京坐高铁去上海,那么同步就是你在高铁上并不能做别的事情,只有等待你到达了上海才能进行下一个动作(如果高铁出事,则就是抛出异常呗)。异步就是你小子在高铁上还买了一张返程的票,高铁是不会等待你返程的票入账才继续向上海进发的。

 二、同步可以保证什么?异步可以做到什么?

简单的就synchronized的作用来阐述同步可以保证:

访问资源的安全性,安全的访问一个共享的资源是程序运行的主要保证条件之一,一个共享的资源极有可能被异步的多线程同时更改,a线程取得并修改的同时b线程就将它复原了,那么这一次的操作岂不是相当于没做了,如果后续a线程的某些业务还要获取这个资源呢?拿到的数据不就是脏数据了?

它能够很好的做到同一时间仅能有同一线程持有当前这个资源。也就相当于当我拿到这个资源时,其他的线程就别想来拿了,除非我的操作做完了或者我主动的释放这个资源的使用权。这里通常叫做拿到锁,释放锁(锁是针对某一片打上同步关键字的资源上的锁,拿到锁就是占有资源,释放锁就是取消占有)。

但是异步任务在不影响业务的执行安全下,可以实现耗时操作的同时进行,又不用等待它执行结束,既提高了程序的速度也提升了效率。

三、synchronizad关键字怎么用?

这里主要简述三种使用方法:

1、首先它可以锁住代码块:

 while (sum <= 19) synchronized (this){
            sum++;
            System.out.println(Thread.currentThread().getName()+","+sum);
        }

这里就是获取当前实例对象的这把锁,谁实例化这个实例,执行对应的方法谁就可以占用这把锁,但是!要求是必须是多个线程同时来抢同一个实例的锁才行。你不能创建两个实例,不然就有两把锁了,因为你每new一个实例,虚拟机堆就会多一个实例,二者是不同的实例,那么显然它俩的锁也不再是同一把,最多算是同一个模具造出来的。

2、其次它可以锁住实例方法:

 synchronized void setSum(){
        sum = 0;
    }

这里大家不妨来看一下StringBuffer的某个方法源码:

  public synchronized char charAt(int index) {
        return super.charAt(index);
    }

这里可以发现源码里也是在方法上加同步关键字将方法上锁,它和锁代码块的原理是一样的,只对多个线程操作同一个实例的同一个方法时才会出现竞争锁和排队拿锁的情况。所以StringBuffer是线程安全的,但是同步操作又是比异步操作要慢的。

3、最后它还可以加在静态实例方法上:

 static void setSum(int num) {
        synchronized (Threads.class){
            sum = num;
        }
   }

这里的Threads.class是方法所属的类的字节码,我们知道一个public的静态方法,我们可以去直接使用它,那么如果它要是被多个线程同时访问了怎么办?又正好这里面具备一些标志操作,如果不上锁的话是不是会出现脏读等现象?所以加上这样一把在虚拟机堆中的锁,是保证安全访问资源的必要。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ForestSpringH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值