Java 线程间通信

原文:https://www.studytonight.com/java/interthread-communication.php

Java 提供了避免使用线程间通信的线程池的好处。对象类的wait()notify()notifyAll()方法用于此目的。这些方法在对象中作为最终方法实现,因此所有类都有它们。所有这三个方法只能从一个同步的上下文中调用

  • wait()告诉调用线程放弃监视器并进入睡眠,直到其他线程进入同一个监视器并调用 notify。
  • notify()唤醒同一对象上调用 wait()的线程。
  • notifyAll()唤醒同一对象上所有调用 wait()的线程。

wait()sleep()的区别

| 等待() | 睡眠() | | 从同步块调用 | 没有这样的要求 | | 监视器被释放 | 监视器未释放 | | 调用 notify()或 notifyAll()方法时唤醒。 | 调用 notify()或 notifyAll()方法时不会唤醒 | | 不是静态方法 | 静态法 | | wait()通常用于条件 | sleep()方法只是用来让你的线程进入睡眠状态。 |

线程池

池化通常通过循环实现,即重复检查某些条件。一旦条件成立,就采取适当的措施。这浪费了 CPU 时间。

Java 中的线程死锁

Deadlock condition in Multithreading

死锁是一种完全锁定的情况,此时没有线程可以因为缺乏资源而完成其执行。上图中,线程 1 持有资源 R1,需要另一个资源 R2 来完成执行,但是 R2 被线程 2 锁定,线程 2 需要 R3,R3 又被线程 3 锁定。因此,他们中没有一个人能完成任务,陷入僵局。

例子

在本例中,多个线程正在访问导致死锁情况的同一方法。当一个线程持有该资源并且不释放它时,其他线程将会等待,并且在死锁条件下,等待时间永远不会结束。

class Pen{}
class Paper{}

public class Write {

  public static void main(String[] args)
  {
     final Pen pn =new Pen();
     final Paper pr =new Paper();

     Thread t1 = new Thread() {
        public void run()
        {
            synchronized(pn)
            {
                System.out.println("Thread1 is holding Pen");
                try{
                    Thread.sleep(1000);
                }
                catch(InterruptedException e){
                  // do something
                }
                synchronized(pr)
                {  
                  System.out.println("Requesting for Paper"); 
                }
            }
        }
      };
      Thread t2 = new Thread() {
          public void run()
          {
              synchronized(pr)
              {
                  System.out.println("Thread2 is holding Paper");
                  try {
                      Thread.sleep(1000);
                  }
                  catch(InterruptedException e){
                      // do something
                  }
                  synchronized(pn)
                  {  
                      System.out.println("requesting for Pen"); 
                  }
              }
          }
      };

      t1.start();
      t2.start();
  }
}

线 1 拿着笔线 2 拿着纸