这三个方法依赖于同一个锁对象,,也就是说只能采用同一个锁的对象的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(); }
}}
相关文章
- 基于Java socket和多线程的简易聊天小程序
- 黑马程序员—9—Java基础:有关多线程的学习笔记和学习心得体会
- [置顶] Java的多线程状态及其他
- java多线程(六)-线程的状态和常用的方法
- Java 并发编程之Runnable和Thread实现多线程的区别
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
- Java线程池中的execute和submit
- java并发编程(三)线程挂起,恢复和终止的正确方法
- Java 异步线程FutureTask的使用和SwingWorker
- java——多线程——单例模式的static方法和非static方法是否是线程安全的?