java基础之多线程(三)--线程的等待与唤醒

基础方法介绍

wait()

让当前线程进入等待(阻塞)状态,并释放当前线程所持有的锁。直到线程被唤醒

wait(long timeout)

当前线程进入等待(阻塞状态)直到被唤醒或超过指定的时间

wait(long timeout, int nanos)

当前线程进入等待(阻塞)状态,直到被唤醒或超过指定时间或被某个其他线程中断当前线程

notify()

唤醒某个此对象监视器上等待的线程

notifyAll()

唤醒此对象监视器上等待的所有线程

实例说明

wait方法释放锁

1)未使用wait方法

public class WaitAndNotifyTest {
    public static void main(String[] args) throws InterruptedException {
        Thread1 t1 = new Thread1("t1");

        synchronized (t1) {
            System.out.println(Thread.currentThread().getName() + " start t1");
            t1.start();
            System.out.println(Thread.currentThread().getName() + " continue");
        }
    }

}

class Thread1 extends Thread {
    Thread1(String threadName) {
        super(threadName);
    }

    @Override
    public void run() {
        synchronized (this) {
            System.out.println(Thread.currentThread().getName() + " start");
            try {
                sleep(3000);
                System.out.println(Thread.currentThread().getName() + " end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果:

main start t1
main continue
t1 start
t1 end

2)使用wait方法

public class WaitAndNotifyTest {
    public static void main(String[] args) throws InterruptedException {
        Thread1 t1 = new Thread1("t1");

        synchronized (t1) {
            System.out.println(Thread.currentThread().getName() + " start t1");
            t1.start();

            /**
             * 虽然t1.wait()是通过“线程t1”调用的wait()方法,
             * 但是调用t1.wait()的地方是在“主线程main”中。而主线程必须是“当前线程”,
             * 也就是运行状态,才可以执行t1.wait()。所以,此时的“当前线程”是“主线程main”!
             * 因此,t1.wait()是让“主线程”等待,而不是“线程t1”!
             */
            System.out.println(Thread.currentThread().getName() + " wait");
            t1.wait();

            System.out.println(Thread.currentThread().getName() + " continue");
        }
    }

}

class Thread1 extends Thread {
    Thread1(String threadName) {
        super(threadName);
    }

    /**
     * 在此的示例中,去掉了notify()之后,程序确实也能正常执行。
     * 那是因为"t1对象的同步锁"上只有两个线程:"主线程"和"t1线程"。"t1线程"执行完毕之后,没有其它线程再来和"主线 
     * 程"竞争这个同步锁了("主线程"也就没有继续等待的必要了)。于是,“主线程”就被唤醒从而继续执行了。
     *
     * 虽然去掉了notify(),程序也能正常执行;但是还是建议在程序中加上notify()。
     *
     * 补充说明一下"执行wait()进入等待状态的线程,有下面4种唤醒方式。"
     * (01) 通过notify()唤醒
     * (02) 通过notifyAll()唤醒
     * (03) 通过interrupt()中断唤醒
     * (04) 如果是通过调用wait(long timeout)进入等待状态的线程,当时间超时的时候,也会被唤醒。
     */
    @Override
    public void run() {
        synchronized (this) {
            System.out.println(Thread.currentThread().getName() + " start");
            try {
                System.out.println(Thread.currentThread().getName() + " notifty");
                notify();
                sleep(3000);
                System.out.println(Thread.currentThread().getName() + " end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果:

main start t1
main wait
t1 start
t1 notifty
t1 end
main continue

由结果看出:

  • 未使用wait方法时,主线程执行完毕后,新线程才开始执行;
  • 使用wait方法后,在t1.wait时,主线程释放了其持有的t1对象同步锁,子线程获取到同步锁后开始执行,子线程运行完毕后主线程重新获取到锁后继续执行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值