(1)该三个方法必须在同步方法或同步块中调用,否则会报错: current thread is not owner
(2)wait,notify,notifyAll方法。
wait():进入休眠状态,然后会即刻释放锁。(被唤醒后需要重新获取到锁才能执行)
notify() :唤醒在休眠状态的线程,然后执行完同步代码块就会释放对象的锁。使得调用 wait()方法的线程从等待队列移入到同步队列中,等待再一次获取到锁。
notifyAll():唤醒在全部休眠状态的线程,然后执行完同步代码块就会释放对象的锁。使得调用 wait()方法的线程从等待队列移入到同步队列中,等待再一次获取到锁。
(3)线程的生命周期分几个阶段:5个阶段:
1、新建,是刚使用new方法,new出来的线程;
2、就绪,是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段;
3、运行,当就绪的线程被调度并获得CPU资源时,便进入运行状态;
4、阻塞,在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态;
5、销毁,线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁。
public class demo implements Runnable{
public int a=1;
public synchronized void method() throws InterruptedException {
while (true){
if (a % 2 == 0) {
//测试释放立即释放锁
//测试得出线程执行wait()方法后,相当于对象退出对象锁了。
// System.out.println(1);
// Thread.sleep(3000);
wait();
}
System.out.println(Thread.currentThread().getName()+":"+a);
Thread.sleep(1000);
a++;
notify();
}
}
public synchronized void method1() throws InterruptedException {
while (true){
if (a % 2 == 1) {
wait();
}
System.out.println(Thread.currentThread().getName()+":"+a);
a++;
//测试释放立即释放锁
System.out.println("释放");
notify();
Thread.sleep(10000);
}
}
@Override
public void run() {
try {
method();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
demo d = new demo();
Thread t = new Thread(d);
Thread t1 = new Thread(new rundemo(d));
t.start();
t1.start();
}
}
public class rundemo implements Runnable{
demo d=null;
public rundemo(demo d){
this.d=d;
}
@Override
public void run() {
try {
// d.method();
d.method1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(4)总结:
1.wait( ),notify( ),notifyAll()都不属于Thread类,而是属于Object基础类,也就是每个对象都有wait( ),notify( ),notifyAll( )的功能,因为每个对象都有锁,锁是每个对象的基础,当然操作锁的方法也是最基础了。
2.当需要调用以上的方法的时候,一定要对竞争资源进行加锁,如果不加锁的话,则会报 IllegalMonitorStateException异常。(意思是要在同步代码块或锁里面使用这些方法)
3.假设有三个线程执行了obj.wait( ),那么obj.notifyAll()则能全部唤醒tread1,thread2,thread3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,tread1,thread2,thread3只有一个有机会获得锁继续执行,具体执行哪个线程由JVM决定,例如tread1,其余的需要等待thread1释放obj锁之后才能继续执行。
4.当调用obj.notify/notifyAll后,调用线程依旧持有obj锁,因此,thread1,thread2,thread3虽被唤醒,但是仍无法获得obj锁。直到调用线程退出synchronized块,释放obj锁后,thread1,thread2,thread3中的一个才有机会获得锁继续执行。
本文详细介绍了Java中wait、notify和notifyAll方法的使用,强调它们必须在同步环境中调用,否则会抛出异常。讨论了线程的生命周期,并通过代码示例展示了wait和notify如何在同步方法中协调线程执行。同时,总结了wait、notify和notifyAll的基础知识,包括它们作为Object类的方法,以及在多线程同步中的作用和限制。
1567

被折叠的 条评论
为什么被折叠?



