Java多线程学习(二)

霸气de小男生 提交于 2019-12-04 18:33:29
  1. 非线程安全:在多个线程对同一个对象中的实例进行并发访问时发生,产生的后果即为脏读。

    线程安全:获得的实例变量的值是经过同步处理的,不会出现脏读现象。

  2. 非线程安全问题存在于实例变量中,即共享的变量 ,但若是方法内部的私有变量,则不存在非线程安全问题。这是因为方法内部的变量是私有的特性造成的。

  3. 如果多个线程同时访问一个对象中的实例变量,则有可能出现非线程安全问题。

    解决方法:在方法前加关键字synchronized即可。在两个线程访问同一个对象中的同步方法时一定是线程安全的。

  4. 多个对象多个锁。关键字synchronized取得的锁都是对象锁,那个线程先访问带synchronized关键字的方法,那个线程就持有该方法所属对象的锁Lock,那么其他线程就只能处于等待状态,前提是多个线程访问的是同一个对象。

    Service service = new Service();
    Thread t1 = new Thread(service);
    Thread t2 = new Thread(service);
    t1.start();
    t2.start();

     但若是多个线程访问多个对象,则jvm就会创建多个锁,则运行结果就是异步的。

    Service service1 = new Service();
    Service service2 = new Service();
    Thread t1 = new Thread(service1);
    Thread t2 = new Thread(service2);
    t1.start();
    t2.start();
  5. 若A线程先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized方法。

    若A线程先持有object对象的Lock锁,B线程如果要调用object对象中的synchronized方法则需等待,也就是同步。

  6. 脏读:在读取实例变量时,此值已经被其他线程更改过了。

  7. synchronized锁重入:在使用synchronized关键字时,当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁的。即在一个synchronized方法/块的内部调用本类的其他synchronized方法/块时,是永远可以得到锁的。

    public class Service{
    public synchronized methodA(){
         methodB();
    }
    public synchronized methodB(){
    }
    }

    线程会同步调用methodA--methodB的顺序。

    可重入锁:自己可以再次获取自己的内部锁。

  8. 可重入锁也支持在父子类继承的环境中。当存在父子类继承关系是,子类是完全可以通过可重入锁的方式调用父类的同步方法。

  9. 当一个线程执行的代码出现异常时,其所持有的锁会自动释放。

  10. 同步不具有继承性。所以override父类的synchronized方法仍需要加上synchronized关键字。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!