[置顶] java 线程的挂起和唤醒

时间:2022-03-17 14:33:11
   这三个方法依赖于同一个锁对象,,也就是说只能采用同一个锁的对象的notify唤醒该锁wait造成的挂起。注意在调用notify和wait方法的时候,首先得获取该锁的使用权限。
wait     方法将线程阻塞。如果有十个线程调用了某个锁对象的wait方法,则10个线程都挂起。如果将这十个线程都唤醒,则需要调用10次该锁对象的notify方法,或者调用一次该锁对象notifyAll方法。
notify   唤醒单个线程。
notifyAll 唤醒所有的线程。

例子如下:雇主有5个工人。当雇主干活命令的使用,则工人工作。如不发送干活命令则工人等待。
 说明:   雇主(employer)有个锁对象(command),雇主雇佣了5个工人(eployee)。          工人的工作(run方法)使用了雇主的锁对象(command)来挂起。          当雇主对所对象command唤醒(调用notify方法)则工人继续工作。  

public class Employee implements Runnable {
      String command;              Employee(String command)       {              this.command = command;       }
       @Override        public void run() {                          synchronized(command )             {                                  System. out.println("I am waiting by invoking command.wait() method");                    try {                        //工人在等待雇主的干活命令。调用雇主的锁对象,挂起当前线程。                            command.wait();                                        System. out.println("Employer notify me by invoking command.notify() method, then I will do my work");                                            } catch (InterruptedException e) {                          // TODO Auto-generated catch block                         e.printStackTrace();                   }                                            System. out.println("I am working" );                }                  } }



public class Employer {      //雇主的锁对象,使用该command.notify方法来要工人干活       String command = "command";       public static void main(String[] sss) throws InterruptedException {                       Employee mployee1 = new Employee(command);            Employee mployee2 = new Employee(command);            Employee mployee3 = new Employee(command);            Employee mployee4 = new Employee(command);            Employee mployee5 = new Employee(command);
            Thread t1 = new Thread(mployee1);            Thread t2 = new Thread(mployee2);            Thread t3 = new Thread(mployee3);            Thread t4 = new Thread(mployee4);            Thread t5 = new Thread(mployee5);
            t1.start();            t2.start();            t3.start();            t4.start();            t5.start();
            Thread. sleep(1000);                         //注意需要得到对应锁对象的使用权限             synchronized(command)            {            //此次调用了两次notify则会有两个工人工作, 如果调用notifyAll则所有的线程都唤醒,所有的工人都干活
               command.notify();               command.notify();            }
      }}