并发编程-基础

在并发要想正确执行需要三要素

  • 原子性
  • 可见性
  • 有序性
 
 

Synchronized关键字

synchronized有加锁的作用,所有的synchronized修饰方法都会顺序执行(占用CPU的顺序)
当synchronized关键字修饰静态方法(static)时升级为类锁,如果不是静态方法两个对象之间没有关系
  • Synchronized关键字执行方式
    • 首先尝试获得锁
    • 如果获得锁,则执行synchronized方法体的内容
    • 如果没有获得锁则等待释放锁,并不断尝试获得锁,一旦锁被释放,多个线程会去尝试获得锁,造成锁竞争
      • 锁竞争问题,如果在高并发,线程数量高,则会引起CPU占用高,或者直接宕机
  • 对象锁同步异步问题?
    • 对象锁之针对synchronized方法生效,对象中所有的synchronized方法都会同步执行,而非synchronized关键字修饰的方法则异步执行
    • 类中有两个synchronized方法,两个线程同时调用两个方法,相互之间是有锁竞争关系的,因为两个方法属于一个对象,我们加的是对象锁
  • 脏读
    • 由于同步与异步执行的个性,如果不从全局考虑,就很容易引起数据的不一致,这就是脏读
      • 多线程访问同一个资源,在线程修改数据的过程中,有另外的数据来读取数据,就会引发脏读
      • 为了避免脏读我们一定要确定修改数据的原子性,并且对读取数据进行同步控制

Synchronized代码块

  • 可以做更细粒度的
  • 可以做对象锁
  • 可以做类锁
  • 可以任意对象锁
  • 同类型锁互斥,不同类型锁互不干扰
  • 不要在线程内部修改锁的引用,引用改变会导致锁失效,在线程中修改锁的属性而不修改锁的引用则不会失效,不会产生线程安全问题
  • 同一个对象内的多个synchronized方法可以锁重入 父子类方法也可以锁重入
 
 
    • 一个线程在获得锁以后执行操作,发生错误抛出异常,则自动释放锁
    • 可以利用抛出异常主动释放锁
    • 程序异常时主动抛出异常防止死锁,无法释放
    • 如果非主动抛出异常而是程序错误抛出的异常释放锁可能导致不一致
 
 
是指两个进程或以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种堵塞现象,若无外力作用,他们都将无法推进下去,
 

线程间的通讯


每个线程都是独立的运行个体,线程通信能让多个线程协同合作
Object类中wait与notify方法可以实现线程通讯
wait与notify必须与synchronized一同使用
wait是释放锁的,notify是不释放锁的
 
 
Notify只会通知一个wait中的线程,并把锁给他不会产生锁竞争问题但是该线程完成之后必须再次notify或者notifyAll,完成类似链式操作
notifyAll 会通知所有的wait中的线程,会产生锁竞争
 

posted @ 2019-04-09 20:39  huxuekuo  阅读(290)  评论(0编辑  收藏  举报