线程等待与唤醒介绍
线程等待与唤醒机制概述 * 又称为线程间通信。 线程等待与唤醒机制相关方法 * void wait(); 等待,让当前正在执行的线程释放cpu的使用权,进入等待。 * void notify(); 唤醒,随机唤醒一个正在等待的线程,让线程进入就绪状态。 * void notifyAll(); 唤醒所有正在等待的线程,让线程进入就绪状态。 * 以上三个方法必须由锁对象调用且必须在同步代码块或同步方法中调用。
线程等待与唤醒案例
定义一个资源共享类。
属性:姓名和性别
开启两个线程:一个输入线程,一个输出线程。
输入线程的任务是给共享对象属性赋值。
输出线程的任务是获取共享对象属性的值,输出在控制台。
要求
输入线程和输出线程要交替执行。
/** * 资源类 */ public class Resource { public String name; public String gender; } /** * 输入线程 */ public class InputThread implements Runnable { // 成员变量 private Resource r; public InputThread(Resource r) { this.r = r; } private int index = 0; public void run() { while(true) { synchronized (r) { if(index % 2 == 0) { r.name = "张三"; r.gender = "男"; } else { r.name = "lisi"; r.gender = "nv"; } try { // 唤醒输出线程 r.notify(); // 当前线程进入等待 r.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 索引加一 index++; } } } /** * 输出线程 */ public class OutputThread implements Runnable { // 成员变量:资源对象 private Resource r; public OutputThread(Resource r) { this.r = r; } public void run() { while(true) { synchronized (r) { // 判断是否已经输入了数据 if(r.name == null) { try { // 让当前线程进入等待 r.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(r.name+"="+r.gender); try { // 唤醒输入线程 r.notify(); // 当前线程进入等待 r.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public class ThreadDemo01 { public static void main(String[] args) { // 创建资源对象 Resource r = new Resource(); // 创建输入线程 Thread tin = new Thread(new InputThread(r)); // 创建输出线程 Thread tout = new Thread(new OutputThread(r)); // 开启线程 tin.start(); tout.start(); } }
常见问题
sleep()和wait()的区别?
sleep方法修饰指定时间,wait可以指定时间也可以不指定。
sleep方法在执行时不会释放锁对象,wait方法会释放锁对象。
sleep方法可以在任意类的任意方法中调用,wait方法必须在同步代码块或同步方法中调用且必须由锁对象调用。