Java多线程编程(第二章)

1. synchronized关键字的使用

“非线程安全”表示在多个线程对同一个对象中的实例变量进行并发访问时,出现”脏读”的现象,也就是取到的数据其实是被修改过的。(多个线程同时操作对象中的实例变)

  • 多个线程访问同一个对象中的同步方法时一定是线程安全的
  • synchronized是可重入锁,可重入锁的概念:自己可以获取自己的内部锁
    ,可重入锁也支持在父子类继承的环境中,当存在父子继承关系时,子类完全可以通过可重入锁调用父类的同步方法
  • 当前线程出现异常时,会释放锁
  • 同步方法不具有继承性
  • synchronized可以修饰方法,也可以修饰代码块
synchronized(任意对象) { }
  • 对象监视器的不同导致运行结果是异步的
  • 静态同步方法的监视器为Class对象
synchronized(Service.class) {

}
  • synchronized(String)同步块与String联合使用时,要注意常量池带来的例外
  • 多线程死锁:因为不同的线程都在等待根本不可能被释放的锁,从而导致所有的任务都无法继续完成。(双方互相持有对方的锁)
  • 内部类与同步:也是同样的规则
    -锁对象的改变:如果在同步期间线程的锁对象发生改变,其同步会被破坏。还有只要对象不变,即使对象的属性被改变,运行的结果还是同步的。

2. volatile关键字的使用

关键字volatile的主要作用是使变量在多线程间可见,强制从公共栈中取得变量的值,而不是从私有数据栈中取得变量的值。

  • 没有使用volatile的内存结构:
    Java多线程编程(第二章)_第1张图片
  • 使用volatile的内存结构:
    Java多线程编程(第二章)_第2张图片
  • volatile和synchronized的区别:
    volatile只能用于修饰变量,synchronized可以修饰方法以及代码块。多线程访问volatile不会发生阻塞,而synchronized会出现阻塞。volatile能保证数据的可见性,但不能保证原子性,而synchronized可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公共内存中的数据做同步。
  • 线程安全主要包括原子性和可见性两个方面
  • 使用原子类进行i++操作
    AtmoicInteger原子类,可以保证操作的原子性,但并不完全安全,在具有逻辑性的情况下输出结果也具有随机性。
  • 关键字synchronized可以使多个线程访问同一个资源具有同步性,而且它还具有将线程工作内存中的私有变量与公共内存中的变量同步功能,即解决一个线程看到对象处于不一致的状态。

你可能感兴趣的:(Java多线程编程(第二章))