synchronized

synchronized原理?

synchronized的底层是使用操作系统的mutex lock实现的:当线程释放锁时,JMM会把该线程对应的工作内存中的共享变量刷新到主内存中,当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。synchronized用的锁是存在Java对象头里的。(临界区由monitor的monitorenter和monitorexit实现)

synchronized的作用?

原子性:操作不可中断,多并发情况下同一时间只有一个线程操作锁内容,相当于单线程。
可见性:当线程获得锁的时候会清空工作内存,从主内存更新最新数据,当释放锁的时候会将更新同步到主内存中。有效避免脏读。
有序性:注意,它不能解决重排序问题,那为什么说它是有序的? 因为synchronized锁住后线程相当于单线程,符合as-if-serial原则.不管怎么重排序优化 它都是不影响最后的结果。(synchronized只保证了代码的有序性,但是变量的赋值操作依旧可以被编译器优化,此时会发生指令重排序; 而volatile就是为了防止编译器指令重排序的。)

synchronized详解?

synchronized:同步锁🔒用法:锁的是共享对象。只和对象有关系。
1、修饰类,synchronized(类名.class){} 锁的是这个类的所有对象;
2、修饰代码块,叫同步语句块,锁调用这个代码块的对象。synchronized(object){}
3、修饰方法,叫同步方法,锁调用这个方法的对象。
4、修饰静态方法,作用范围整个静态方法,锁这个类的所有对象。
(注意:有共享数据才会出现线程安全问题,静态方法、静态变量属于类不属于对象,放在方法区,栈是私有的,其他区域都是共享的。局部变量在栈区)

//修饰类
class Person{
    private volatile static Person person;
    public Person(){
    }
    public static Person getPerson(){
        if(person == null){
            synchronized (Person.class){
                if(person == null){
                    person = new Person();
                }
            }
        }
        return person;
    }
}
//修饰静态方法
class Person1{
    private static Person person1;
    private Person1(){}
    public synchronized static Person getPerson1(){
        if(person1==null){
            person1= new Person();
        }
        return person1;
    }
}
//修饰代码块
public class SynchronizedDemo {
	public void methond() {
// 进入代码块会锁 this 指向对象中的锁;出代码块会释放 this 指向的对象中的锁
	synchronized (this) {
			}
		}
}
//修饰方法
public class SynchronizedDemo {
	public synchronized void methond() {
		}
}

线程中synchronsize的操作过程?

在这里插入图片描述
1、线程状态:启动(NEW)、就绪(RUNNABLE)运行(RUNNING)、阻塞(BLOCKED)、结束(TERMINATED)。(注意线程调度是时间片的抢占方式)
2、线程启动——抢到锁的线程进入运行状态——没抢到锁的线程进入阻塞状态——等到锁释放后,就绪线程开始抢锁———运行完毕后关闭线程
注意事项:
锁内同时只能有一个线程执行,其他线程在阻塞队列或就绪队列中等待释放锁。
锁互斥:thread1争抢到了🔒,正在执行锁里面语句时被调度出去,thread2获得cpu进来发现有🔒就进入阻塞队列里等待thread1释放锁,thread1执行完锁语句后释放锁后,thread才能获得🔒;则thread1和thread2互斥(锁互斥)。
synchronized不能被继承:父类方法有锁,子类继承的方法没锁。synchronized不属于方法的一部分。
定义接口方法时不能使用synchronized;
构造方法不能使用synchronized来修饰,但是可以使用synchronized代码块。
线程抢锁失败就会进入阻塞队列(blocked),等锁释放了再争抢锁。等后台线程执行完了才会结束。
waiting等待集:调用wait()方法线程释放锁进入等待集,一直等待,直到被notify()或notifyAll唤醒。
timed_waiting超时等待:wait()和sleep()等到时间到了继续执行任务。
wait和sleep区别:wait是Object类–sleep是Thread类,wait进入等待集前会释放锁–sleep进入等待集不会释放锁,所有线程都在等他休眠醒来。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值