对象及变量的并发访问

对象及变量的并发访问

java多线程的同步,怎样写出线程安全的程序
 1.synchronized对象监视器为Object时
 2.synchronized对象监视器为Class时
 3.非线程安全是如何出现的
 4.关键字volatile的主要作用
 5.关键字volatile和synchronized的区别及使用情况
synchronized同步方法

非线程安全其实会在多个线程对同一对象中的实例变量进行并发访问时产生,产生的后果是脏读,也就是取到的数据其实被更改过
线程安全就是获得实例变量的值经过同步处理的,不会产生脏读现象
1.方法内的变量为线程安全
 即,方法中的变量不存在非线程安全问题,永远都是线程安全的
2.实例变量非线程安全
 两个线程同时访问一个没有同步的方法,如果同时操作业务对象中的实例变量,则有可能产生非线程安全问题
3.多个对象多个锁
 synchronized取得的锁都是对象锁,而不是把一段代码或方法当作锁
 如果多个线程访问多个对象,就会产生多个锁
4.synchronized方法与锁对象
 调用关键字synchronized修饰的方法一定是排队进行的,只有共享资源的读写访问才需要同步化,如果没有共享资源,根本不需要同步化
 a线程先持有Object对象的Lock锁,B线程可以以异步的方式调用Object对象中非synchronized修饰的方法
 a线程先持有Object对象的Lock锁,B线程要调用Object对象中synchronized修饰的其他方法,需要排队等待。
5.脏读
 发生脏读的情况就是在读取实例变量时此值已经被其他线程修改过了
 脏读一定会出现操作实例变量的情况下,这就是不同线程争抢实例变量的结果
6.synchronized锁重入
 在使用synchronized时,当一个线程对象得到对象锁之后,再次请求对象锁是可以得到该对象的锁的。也就是,在synchronized方法/块
 内部调用本类其他synchronized方法/块时,永远可以得到锁
 这种情况也可以出现在父子类继承关系中,子类完全可以通过可重入锁调用父类的同步方法
7.出现异常,锁自动释放
 当一个线程执行的代码出现异常时,所持有的锁会自动释放
8.同步不具有继承性
 父类中同步方法在子类中重写时,不具有同步性,要同步,需要在子类中添加synchronized
synchronized同步语句块

synchronized同步方法有缺陷,例如a线程调用同步方法执行一个非常耗时的任务,那么B线程则需要等待比较长的时间
synchronized同步方法是对当前对象进行加锁,synchronized代码块是对某一对象进行加锁
1.synchronized同步方法弊端
  a线程调用同步方法执行一个非常耗时的任务,那么B线程则需要等待比较长的时间
2.synchronized同步语句块的使用
  当两个并发线程访问同一个对象Object中的Synchronized(this)同步代码块时,一段时间内,只能一个线程被执行,另外一个线程必须等待
3.synchronized同步语句块解决synchronized同步方法弊端(也就是效率问题)
  当一个线程访问object的一个synchronized代码块时,其他线程也可以访问该object的其他非synchronized同步代码块
4.一半同步,一半异步
  不在synchronized代码块中是异步执行,在synchronized代码块当中是同步惊醒
5.synchronized代码块间的同步性
  在使用Synchronized(this)代码块时要注意,当一个线程访问object的一个Synchronized(this)代码块时,其他线程对同一个object中的其他
  Synchronized(this)同步代码块将被阻塞,这说明对象监视器是同一个(this)
6.Synchronized(this)代码块时锁定当前对象,和Synchronized方法一致
7.将任意对象作为对象监视器
  Synchronized(非this对象x)
  锁非this对象优点:它不会和同一对象中的其他this同步方法争抢锁,大大提高运行效率。
  监视器必须是同一个对象监视器,如果不是同一个对象监视器,就会出现交叉运行
  多线程调用同一个方法(非同步)是随机的,这个有可能出现脏读环境
8.细化验证3个结论
  多个线程同时执行Synchronized(x){}同步代码块呈同步效果
  当其他线程执行x对象中的Synchronized同步方法时呈同步效果
  当其他线程执行x对象方法中的Synchronized(this)代码块时呈同步效果
  原因:Synchronized(x)代码块中x的对象锁与x对象,是同一个锁
9.静态同步synchronized方法与synchronized(class)代码块
  静态同步synchronized方法时class锁,class锁对类的所有对象起作用
  synchronized加到非static方法上是给对象上锁
  synchronized(class)类似。
  总结:静态synchronized方法,所有类对象共用一个锁
        非静态synchronized方法,一个对象一个锁,不同对象不同锁。
10.数据类型String的常量池特性
  由于jvm中具有String常量池缓存的功能,所以大多数情况下,Synchronized(x)代码块不用String作为锁对象
  常量池:String a="a",String b="a" 得出a=b,物理地址一样,所以锁也一样,一个无限处理的线程获得锁,其他对象将不会再获得锁
11.同步synchronized方法的无限等待与解决
  一个对象锁死循环,另外一个线程永远得不到锁
  用同步代码块synchronized(x){},创建不同的x
12.多线程的死锁
  不同的线程都在等待不可能释放的锁,从而导致所有任务无法继续完成。死锁必须避免,因为这会造成线程的假死。经典案例,相互持有对方的锁
13.内置类与静态内置类
  内置类:PrivateClass privateClass = publicClass.new PrivateClass();
  静态内置类 PrivateClass privateClass = new PrivateClass();
14.内置类与同步
  内置类中有两个同步方法,使用的是不同的锁,所以,结果是异步的
  synchronized(class2)获得class2的锁,其他线程要想调用class2中的同步方法,需要等待
15.锁对象的改变
  将任何数据作为同步锁时,需要注意,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则线程之间就是同步的,如果分别获得锁对象
  则线程之间是异步的
  只要锁对象不变,及时锁对象的属性改变,线程也是同步的
volatile关键字

volatile的主要作用是使得变量在多线程之间可见
1.volatile与死循环
  单线程,当程序进入死循环之后,之后的代码不会执行,解决办法,使用多线程
2.解决同步死循环
  多线程
  volatile关键字的作用,是强制从公共堆栈中取值,而非从线程中私有栈中取得变量的值
3.解决异步死循环
  -server模式线程一直在获取线程私有堆栈中的值,当改变属性时,虽然代码被执行,但是更新的确是公共堆栈中的属性值,这是由于私有堆栈
  和公共堆栈中的值不同步造成的
  通过使用volatile关键字,强制从公内存中获取变量的值。
  volatile和synchronized比较:
    volatile是线程同步轻量级实现,所以性能比synchronized要好,volatile只能修饰变量,synchronized可以修饰方法以及代码块
    多线程访问volatile不会阻塞,synchronized会阻塞
    volatile可以保证数据可见性,但不会保证原子性,但是synchronized能保证原子性,也可以保证可见性
    volatile保证的是变量在多线程之间的可见性,synchronized解决的是多线程访问资源的同步性

    线程安全包含两个方面:原子性和可见性,Java的同步机制就是围绕这两个方面来保证线程安全的。

4.volatile非原子性
  volatile只能保证每次从共享内存中读取数据的可见性,并不能保证原子性,如果在修改变量的数据比如i++就有可能产生脏数据
  所以,数据操作要保证原子性需要synchronized同步
5.使用原子类进行i++操作
  使用AtomicInteger()进行i++,它有线程安全的++操作
6.原子类也并不安全
  原子类只能保证++时的安全,多线程还是可以访问其他逻辑代码,所以结果也是脏读数据
7.synchronized代码块有volatile同步的功能
  synchronized包含两个特征:互斥性和可见性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值