一、线程间通信
- 需要三个重要的方法:(java.lang.Object包下)
三种方法使用之前一定要加锁
①wait()
②notify()
③notifyAll()
父线程给子线程传递信息:构造函数
子线程给父线程传递信息: FutureTask:实现Callable接口时,有一个call方法,有返回值
2.方法介绍:
- wait(): 属于Object的方法,任何对象都可以调用
调用wait方法的线程会被阻塞,直到其他线程调用notify()/notifyAll()时,当前线程才可以继续执行。调用了wait方法后,当前线程会释放锁,使其他线程能继续获取锁使用 - notify():通知调用wait方法的(任意一个)线程来继续执行。
(只能通知等待池中任意一个线程,将这个线程放入锁池,开始竞争锁) - notifyAll:通知所有调用wait方法的线程来继续执行。
(从等待池中将所有调用wait方法的线程放入锁池 然后开始竞争锁)
上述涉及两个概念:
① 锁池:存放竞争当前锁的线程
② 等待池:线程调用了对象的wait方法,先释放锁,再进入对象的等待池
注意:
wait()和notify() 操作的必须是同一个对象, 并且调用wait()方法的对象和加锁的对象是同一个对象
3.代码:
Wait.java
/**
* @auther: 巨未
* @DATE: 2019/4/13 0013 10:56
* @Description:
* 子线程
*/
public class Wait extends Thread{
Object o ;
public Wait(Object o){
this.o = o;
}
@Override
public void run() {
synchronized (o){
System.out.println(Thread.currentThread().getName()+" start...");
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" end...");
}
}
}
notify.java
/**
* @auther: 巨未
* @DATE: 2019/4/13 0013 11:08
* @Description:
*/
public class notify extends Thread {
Object o ;
public notify(Object o){
this.o = o;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" start...");
synchronized (o){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
o.notify(); }
System.out.println(Thread.currentThread().getName()+" end...");
}
}
WaitDemo.java
/**
* @auther: 巨未
* @DATE: 2019/4/13 0013 10:54
* @Description:
*/
public class WaitDemo {
public static void main(String[] args) {
Object o = new Object();
Wait wait = new Wait(o);
wait.setName("wait");
notify notify = new notify(o);
notify.setName("notify");
wait.start();
notify.start();
}
}
执行结果:调用了wait()方法被阻塞时,notify()方法通知调用的wait(),继续执行。