java的wait_javawait()⽅法⽤法详解
⼀、wait(), notify(), notifyAll()等⽅法介绍
1.wait()的作⽤是让当前线程进⼊等待状态,同时,wait()也会让当前线程释放它所持有的锁。“直到其他线程调⽤此对象的 notify() ⽅法或 notifyAll() ⽅法”,当前线程被唤醒(进⼊“就绪状态”)
3.wait(long timeout)让当前线程处于“等待(阻塞)状态”,“直到其他线程调⽤此对象的notify()⽅法或 notifyAll() ⽅法,或者超过指定的时间量”,当前线程被唤醒(进⼊“就绪状态”)。
⼆、wait 的⽤法详解(这⾥的t1是⼀个线程(锁))
// main(主线程)
synchronized(t1) {
try {
t1.start();
t1.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
// 在 t1 线程中唤醒主线程
synchronized (this) { //这⾥的 this 为 t1
}
注:
1、synchronized(t1)锁定t1(获得t1的监视器)
2、synchronized(t1)这⾥的锁定了t1,那么wait需⽤t1.wait()(释放掉t1)
3、因为wait需释放锁,所以必须在synchronized中使⽤(没有锁定则么可以释放?没有锁时使⽤会抛出IllegalMonitorStateException(正在等待的对象没有锁))
4. notify也要在synchronized使⽤,应该指定对象,t1. notify(),通知t1对象的等待池⾥的线程使⼀个线程进⼊锁定池,然后与锁定池中的线程争夺锁。那么为什么要在synchronized使⽤呢? t1. notify()需要通知⼀个等待池中的线程,那么这时我们必须得获得t1的监视器(需要使⽤synchronized),才能对其操作,t1. notify()程序只是知道要对t1操作,但是是否可以操作与是否可以获得t1锁关联的监视器有关。
5. synchronized(),wait,notify() 对象⼀致性
6. 在while循环⾥⽽不是if语句下使⽤wait(防⽌虚假唤醒spurious wakeup)
三、证明wait使当前线程等待
class ThreadA extends Thread{
public ThreadA(String name) {
super(name);
}
public void run() {
synchronized (this) {
try {
Thread.sleep(1000); // 使当前线阻塞 1 s,确保主程序的 t1.wait(); 执⾏之后再执⾏ notify() } catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" call notify()");
// 唤醒当前的wait线程
}
}
}
public class WaitTest {
public static void main(String[] args) {
ThreadA t1 = new ThreadA("t1");
synchronized(t1) {
try {
// 启动“线程t1”
System.out.println(Thread.currentThread().getName()+" start t1");
t1.start();
/
/ 主线程等待t1通过notify()唤醒。
System.out.println(Thread.currentThread().getName()+" wait()");
t1.wait(); // 不是使t1线程等待,⽽是当前执⾏wait的线程等待
System.out.println(Thread.currentThread().getName()+" continue");
try catch的使用方法} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
四、wait(long timeout)超时被唤醒
class ThreadA extends Thread{
public ThreadA(String name) {
super(name);
}
public void run() {
System.out.println(Thread.currentThread().getName() + " run ");
// 死循环,不断运⾏。
while(true){;} // 这个线程与主线程⽆关,⽆ synchronized
}
}
public class WaitTimeoutTest {
public static void main(String[] args) {
ThreadA t1 = new ThreadA("t1");
synchronized(t1) {
try {
// 启动“线程t1”
System.out.println(Thread.currentThread().getName() + " start t1");
t1.start();
// 主线程等待t1通过notify()唤醒 或 notifyAll()唤醒,或超过3000ms延时;然后才被唤醒。System.out.println(Thread.currentThread().getName() + " call wait ");
t1.wait(3000);
System.out.println(Thread.currentThread().getName() + " continue");
t1.stop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论