Java 多线程 (PART XV) wait()/notify()方法

23 篇文章 0 订阅
23 篇文章 1 订阅

线程的状态

线程状态图(还是这张图)
这里写图片描述

进入runnable状态的条件

1:调用sleep方法后经过的时间超过了指定的休眠时间
2:线程调用的IO阻塞已经返回,阻塞方法执行完毕
3:线程调用的jion的线程执行完毕
4:正在运行running状态的线程主动调用yield方法放弃对CPU资源的占用
5:线程获得同步监视器

从running状态离开的条件

1:线程正常结束,或者异常终止
2:线程调用sleep方法,使得线程进入休眠状态
3:线程调用join方法,使得线程进入阻塞状态,等待join的线程运行完成
4:线程获得同步监视器失败
5:线程调用了wait方法,此时正在等待某个通知
6:调用阻塞IO方法

wait()方法

作用:
可以调用该方法的线程释放共享资源的锁,然后从running状态退出,进入等待队列,直到再次被唤醒。
注:
这是Object的方法,调用之后释放锁
这里写图片描述

notify()方法

作用:
可以随机唤醒等待队列中等待同一个共享资源的一个线程,并使得该线程退出等待队列,进入Runnable状态。
注:
这是Object的方法,调用之后不释放锁

notifyall()方法

作用:
可以使得所以正在等待队列等待同一个共享资源的线程都被唤醒,从等待队列退出,进入Runnable状态,此时优先级最高的线程首先进入Running状态,不过也可能是随机的,这取决于JVM的具体实现。
注:
这是Object的方法,调用之后不释放锁

示例代码:

package notifyTest;
class Service{
    public void testMethod(Object lock) {
        try {
            synchronized(lock) {
                System.out.println(" begin wait() ThreadName="+Thread.currentThread().getName());
                lock.wait();
                System.out.println(" end  wait() ThreadName="+Thread.currentThread().getName());
            }

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
/**
 * 线程A
 * */
class ThreadA extends Thread{
    private Object lock;
    public ThreadA(Object lock) {
        this.lock=lock;
    }
    @Override
    public void run() {
        Service service=new Service();
        service.testMethod(lock);
    }
}
/**
 * 线程B
 * */
class ThreadB extends Thread{
    private Object lock;
    public ThreadB(Object lock) {
        this.lock=lock;
    }
    @Override
    public void run() {
        Service service=new Service();
        service.testMethod(lock);
    }
}
/**
 * 线程C
 * */
class ThreadC extends Thread{
    private Object lock;
    public ThreadC(Object lock) {
        this.lock=lock;
    }
    @Override
    public void run() {
        Service service=new Service();
        service.testMethod(lock);
    }
}
/**
 * 通知线程
 * */
class NotifyThread extends Thread{
    private Object lock;
    public NotifyThread (Object lock) {
        this.lock=lock;
    }
    @Override
    public void run() {
        synchronized (lock) {
            lock.notify();//随机唤醒等待队列中等待同一个共享资源的线程
            //lock.notifyAll();//唤醒等待队列中所有等待同一个共享资源的线程
        }
    }
}
public class Main {
    public static void main(String[]args) {

        try {
            Object lock=new Object();
            ThreadA threada=new ThreadA(lock);
            ThreadB threadb=new ThreadB(lock);
            ThreadC threadc=new ThreadC(lock);
            threada.start();
            threadb.start();
            threadc.start();
            /**
             * 以上是启动3个线程
             * 
             * 下面启动通知线程
             * */
            Thread.sleep(10);
            NotifyThread notifyThread=new NotifyThread(lock);
            //此时启动的四个线程都在使用同一个共享资源
            notifyThread.start();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

运行结果:

 begin wait() ThreadName=Thread-2
 begin wait() ThreadName=Thread-1
 begin wait() ThreadName=Thread-0
 end  wait() ThreadName=Thread-2

结果分析

此时,NotifyThread线程只调用了notify方法,所以从等待队列中随机唤醒一个等待同一个共享资源的线程。

稍作修改,调用notifyAll()方法

/**
 * 通知线程
 * */
class NotifyThread extends Thread{
    private Object lock;
    public NotifyThread (Object lock) {
        this.lock=lock;
    }
    @Override
    public void run() {
        synchronized (lock) {
            //lock.notify();//随机唤醒等待队列中等待同一个共享资源的线程
            lock.notifyAll();//唤醒等待队列中所有等待同一个共享资源的线程
        }
    }
}

运行结果:

 begin wait() ThreadName=Thread-0
 begin wait() ThreadName=Thread-2
 begin wait() ThreadName=Thread-1
 end  wait() ThreadName=Thread-1
 end  wait() ThreadName=Thread-2
 end  wait() ThreadName=Thread-0

结果分析:

此时,等待队列中有三个使用同一个共享资源的线程,notifyAll会将他们全都唤醒。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值