对象以及变量的并发访问

1、synchronized同步方法

    非线程安全的问题存在于实例变量中,方法内部的私有变量是线程安全的

    synchronized获取的是对象锁,多个线程访问同一个对象:同步;多个线程访问多个对象:异步;

    只有共享资源才的读写访问才需要同步

    脏读:读取变量时,变量值已经被其他线程更改了

    synchronized具有锁重入的功能,当一个线程获得锁之后,再次请求次对象的锁,是可以再次得到该对象的锁的。

    当存在父子类继承关系时,子类完全可以通过“可重入锁”调用父类的同步方法

    出现异常,锁将自动释放

    同步不具有继承性

2、同步语句块

    使用synchronized声明方法的弊端:如果同步方法耗时较长,则执行了效率低

    不在synchronized代码块里的是异步执行,在synchronized块中就是同步执行

    synchronized代码块之间具有同步性(对象监视器是同一个)

    synchronized(this)代码块也是锁定当前对象

    多个线程调用同一个对象中的不同名称的synchronized同步方法或者synchronized(this)同步代码块,调用的效果就是按顺序执行

     synchronized(非this对象X):多个线程持有“对象监视器”为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象X)同步代码块中的代码。

    锁非this对象的优点:与同步方法是异步,提升效率

    静态同步synchronized静态方法与synchronized(class):

    synchronized用在静态方法上或者是synchronized(class)代码块,是对当前文件对应的class类进行加锁,calss锁可以对类的所有对象起作用;加在非静态方法上是给对象加锁。

    String类型不适合做为锁对象:常量池的特性

    可使用synchronized代码块来解决synchronized方法无限等待的问题

    死锁:你等我我等你,然后都等不到;jstack -l -pid 查看死锁

    内部内和内部静态类的同步问题:

    内部内:实例化的方式——outClass.new InnerClass() ;不在同一个包要把内部类声明成public

    静态内部类:内部类前 加static

    注意锁的改变:

    只要锁对象不变,对象属性改变也不会改变同步结果

  *volatile关键字:强制从公共堆栈中取的变量的值,而不是从线程私有数据栈中取得变量值。

                              

     volatile的使用场景是多个线程中可以感知实例变量被更改了,强制线程对数据的读写及时影响到主内存。

    synchronized关键字和volalite的比较:

    1)volatile性能笔记synchronized的要好,但是只能修饰变量,synchronized可以修饰变量和方法以及代码块

    2)volatile不会发生阻塞,synchronized会发生阻塞

    3)volatile增加了实例变量在线程之间的可见性,但是不保证原子性;synchronized可以保证原子性,也可间接的保证可见性。

    原子类:

    一个原子类型就是一个原子操作可用的类型,它在没有锁的情况下可以做到线程安全。

   原子类在具有逻辑性的情况下输入结果也是具有随机性的

    synchronized代码有volatile同步的功能:

    synchronized可以使多个线程访问同一个资源具有同步性,而且它还具有将线程工作内存中的变量与公共内存中的变量同步的功能。

     “外练互斥,内修可见”

    

    

  

猜你喜欢

转载自my.oschina.net/u/2464465/blog/1818318