synchronized、volatile关键字详解

一.关键字

1.synchronized关键字:

        a.重量级锁,功能完整的锁

        b.修饰类、方法、静态方法、代码块,但不可以在声明的时候修饰

        c.synchronized是实现同步的基础,Java中不管是对象还是方法,都可加上锁。synchronized分为三种

                对象锁:对于普通同步方法,锁是当前实例对象。

                ①、在一个线程访问一个对象中一个加synchronized的非静态方法时,会将整个对象都锁住。整个对象中加锁的方法之间都互斥,加锁的和不加锁的不互斥。加锁的方法之间不能在两个线程之间同时运行,需要一个运行完另一个在运行

                类锁:对于静态同步方法,锁是当前类的Class对象

                ①、类锁static,它不属于对象,属于类。static修饰的加锁的互斥

                ②、对象锁和类锁不互斥,互不干扰。

                同步代码块:对于同步方法块,锁是Synchonized括号里配置的对象。

                ①、锁某一个全局变量,锁住的是变量的值,而不是变量本身

        

2.volatile关键字:

        a.轻量级锁,功能不全的锁

        b.只修饰变量,在声明的时候修饰

        c.volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值

        d.volitile保障正确的读到(其他线程写完之后可以立刻感知到)及保证了写后读:
        导线一次只能通过一组数据,需要排队从高速缓存返回内存,volitile来排队返回的数据中之所以精确的到达内存的这个地址,是因为返回的数据中存有内存地址。volitile实现了返回时告诉缓存,和我相同对应地址的别的线程修改的数据失效了,需要重新计算。volatile将还在计算的数据被销毁,已经计算完毕的进入排队队列的数据不能被销毁。所有volatile不能完全代替synchronized.
volatile只能保证读正确,不能保证写正确

        e.volatile防止指令重排序

3.两者区别:

synchronized锁住的元素在高速缓存中只能有一个,在一个线程读写时,其余线程连读都不让读;而volitile只能保证写后读,但往回更新是不能保障的

二、如何避免死锁

  • 避免一个线程同时获取多个锁。
  • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
  • 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。
  • 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。

三、让出cpu的三种方式 

  • Thread.sleep(0):立即让出CPU,在多少秒内不参与CPU的竞争。然后在数字到0时继续参与竞争。
  • Thread.yield():主动让出cpu进入就绪态,但不是立即让出CPU的意思。 但是当我们调用Thread.yield()的那一刻,并不意味着当前线程立马释放cpu资源,这是因为获得时间片的线程从runable切换到running仍需要一定的准备时间,这段时间当前线程仍可能运行一小段时间。
  • 我们写多线程的时候不匹配的话直接让出CPU,提高性能

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值