美文网首页
java进程间协作

java进程间协作

作者: SeaRise | 来源:发表于2018-02-01 11:00 被阅读26次
  • synchronized

    • 对象锁:
      • 每一个Java对象都可以用作一个实现同步的锁,称为内置锁,线程进入同步代码块之前自动获取到锁,代码块执行完成正常退出或代码块中抛出异常退出时会释放掉锁。
      • 内置锁为互斥锁,即线程A获取到锁后,线程B阻塞直到线程A释放锁,线程B才能获取到同一个锁。
      • 内置锁使用synchronized关键字实现
    • 类锁
      • 对static方法用synchronized修饰实现
      • 对class对象加锁
      • 与对象锁互不干涉
  • 锁池和等待池


    无标题.png
    • 在java中,每个对象都有两个池,锁(monitor)池和等待池。

    • 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。

    • 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池中

  • wait,notify,notifyall

    • 这三个方法的调用前提是持有锁。

    • 如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。

    • 当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。

    • 优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。

    • 由此可知,调用notify()可能会造成死锁,调用notifyAll()不会死锁。因为notify()唤醒一个线程后,那个线程执行完了没有notify(),则剩下的线程全部都在等待池,没有线程执行,造成死锁。而notifyAll()是让所有等待池的线程都进入锁池,所以不会有上诉的现象发生。

  • wait,sleep

    • wait方法是让持有锁的线程释放锁,进入等待池。
    • sleep的方法是让线程让出cpu的使用权,本身仍然持有锁。

相关文章

网友评论

      本文标题:java进程间协作

      本文链接:https://www.haomeiwen.com/subject/ufgkzxtx.html