关键字

1.Synchronized

介绍

synchronized是Java实现同步的一种机制,它属于Java中关键字,是一种jvm级别的锁。synchronized锁的创建和释放是此关键字控制的代码的开始和结束位置,锁是由jvm控制的创建和释放的,正是因为这一点,synchronized锁不需要手动释放,哪怕是代码出现异常,jvm也能自动释放锁。

为什么要使用synchronized

在并发编程中存在线程安全问题,主要原因有:1.存在共享数据 2.多线程共同操作共享数据。关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的变化可见(可见性),即可以代替volatile。

实现原理

synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性

应用方式

对于普通的同步方法:
锁是当前的对象
对于静态函数的同步方法:
锁是静态函数所在类的class对象
对于同步方法块的内容:
锁是指Synchonized括号里配置的对象

2.synchronized和Lock的区别

 synchronized是java内置关键字,在jvm层面,Lock是个java类;
 synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
 synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
 用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
 synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)
 Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。

3.volatile

Java程序中,为了提高程序运行效率,编译器会自动对其进行优化,把经常被访问的变量缓存起来,程序在读取变量时可能直接从缓存(例如寄存器)中来读取这个值,而不会从内存中取。但当遇到多线程编程时,变量的值可能因为别的线程而改变,但是缓存的值不会相应的发生变化,从而造成应用程序读值和实际值不一样。
volatile是一个类型修饰符,被设计用来修饰被不同线程访问和修改的变量。被volatile修饰的变量,系统每次用到它都会直接从内存中提取,而不利用内存。所以被修饰的变量,所有线程线程在任何时候看到的值都是相同的。
volatile不能保证原子性,所以volatile不能代替Synchronized。而且volatile会降低程序的运行效率,所以能不用则不用。

posted @ 2020-02-11 01:09  程序员自习室  阅读(207)  评论(0)    收藏  举报