Java,wait,notify实例与理解(一)

Java 专栏收录该内容
515 篇文章 2 订阅

最通俗易解的方式:

实例1:

class ThreadA {

    static Object o1 = new Object();//可以是任意一个对象,或者自定义的对象

    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();
        System.out.println("b is start....");
        synchronized (o1)// 主线程获取o1的对象锁
        {
            try {
                System.out
                        .println("Waiting for b to complete...");
                o1.wait();//o1的对象锁释放,主线程进入等待状态
                System.out
                        .println("Completed.Now back to main thread");
            } catch (InterruptedException e) {
            }
        }
        System.out.println("Total is :" + b.total);
    }
}

class ThreadB extends Thread {
    int total;
    public void run() {
        synchronized (o1) {//ThreadB获取o1的对象锁
            System.out.println("ThreadB is running..");
            for (int i = 0; i < 5; i++) {
                total += i;
                System.out.println("total is " + total);
            }
            o1.notify();//ThreadB释放o1的对象锁,通知其他等待o1对象锁的线程继续运行
        }
    }
}

o1.wait()没设置时间,需要o1.notify(),主线程才能继续运行

输出有以下两种情况:

b is start....
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Waiting for b to complete...


b is start....
Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Completed.Now back to main thread
Total is :10

实例2:

//o1.notify();这句话注释掉

输出的一种情况:

b is start....
Waiting for b to complete...
Sat Sep 29 10:07:56 CST 2018
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10

o1.wait()没设置时间,没有o1.notify(),主线程不能继续运行

实例3:o1.wait(xxx)设置时间,没有o1.notify()


class ThreadA {

    static Object o1 = new Object();

    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();
        System.out.println("b is start....");
        synchronized (o1)// 主线程获取o1的对象锁
        {
            try {
                System.out
                        .println(new Date() + "Waiting for b to complete...");
                o1.wait(3000);//o1的对象锁释放2s,主线程进入等待状态,需要通知才能获取锁
                System.out
                        .println(new Date() + "Completed.Now back to main thread");
            } catch (InterruptedException e) {
            }
        }
        System.out.println("Total is :" + b.total);
    }
}

class ThreadB extends Thread {
    int total;

    public void run() {
        synchronized (o1) {//ThreadB获取o1的对象锁
            System.out.println("ThreadB is running..");
            for (int i = 0; i < 5; i++) {
                total += i;
                System.out.println("total is " + total);
            }
            try {
//               Thread.sleep(5000);//ThreadB执行完后,主线程继续执行
               Thread.sleep(2000);//ThreadB先执行完,然后主线程再等待1s,主线程继续执行
//               Thread.sleep(3000);//ThreadB先执行完,紧接着主线程继续执行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //o1.notify();//ThreadB释放o1的对象锁,通知其他等待o1对象锁的线程继续运行
        }
    }
}

输出:

Thread.sleep(5000);
b is start....
Sun Sep 30 14:11:05 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:11:10 CST 2018Completed.Now back to main thread
Total is :10

Thread.sleep(2000);
b is start....
Sun Sep 30 14:11:41 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:11:44 CST 2018Completed.Now back to main thread
Total is :10 
 
Thread.sleep(3000);
b is start....
Sun Sep 30 14:09:51 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:09:54 CST 2018Completed.Now back to main thread
Total is :10

实例4:o1.wait(xxx)设置时间,有o1.notify()

class ThreadA {

    static Object o1 = new Object();

    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();
        System.out.println("b is start....");
        synchronized (o1)// 主线程获取o1的对象锁
        {
            try {
                System.out
                        .println(new Date() + "Waiting for b to complete...");
                o1.wait(3000);//o1的对象锁释放2s,主线程进入等待状态,需要通知才能获取锁
                System.out
                        .println(new Date() + "Completed.Now back to main thread");
            } catch (InterruptedException e) {
            }
        }
        System.out.println("Total is :" + b.total);
    }
}

class ThreadB extends Thread {
    int total;

    public void run() {
        synchronized (o1) {//ThreadB获取o1的对象锁
            System.out.println("ThreadB is running..");
            for (int i = 0; i < 5; i++) {
                total += i;
                System.out.println("total is " + total);
            }
            try {
//               Thread.sleep(5000);//ThreadB执行完后,主线程继续执行,有无o1.notify();均是
//               Thread.sleep(2000);//ThreadB先执行完,主线程不用再等待1s,主线程继续执行
               Thread.sleep(3000);//ThreadB先执行完,紧接着主线程继续执行,有无o1.notify();均是
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            o1.notify();//ThreadB释放o1的对象锁,通知其他等待o1对象锁的线程继续运行
        }
    }
}

输出:

Thread.sleep(5000);
b is start....
Sun Sep 30 14:11:05 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:11:10 CST 2018Completed.Now back to main thread
Total is :10

Thread.sleep(2000);
b is start....
Sun Sep 30 14:14:59 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:15:01 CST 2018Completed.Now back to main thread
Total is :10
 
Thread.sleep(3000);
b is start....
Sun Sep 30 14:09:51 CST 2018Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Sun Sep 30 14:09:54 CST 2018Completed.Now back to main thread
Total is :10

实例3,4中,sleep不释放锁,所以主线程要等待,如果换成o1.wait,会释放锁,有无o1.notify时,可以自行实验。

 

要分析这个程序,首先要理解 notify() 和 wait(),这两个方法本来就不属于 Thread 类,而是属于最底层的 object 基础类的,也就是说不光是 Thread,每个对象都有  notify 和wait 的功能,为什么?因为他们是用来操纵锁的,而每个对象都有锁,锁是每个对象的基础,既然锁是基础的,那么操纵锁的方法当然也是最基础了。

参考:https://blog.csdn.net/defonds/article/details/4923775?utm_source=copy

 

更多企业内的技术应用和使用技巧,请移步至我的公众号【程序员实用技能】

图片

 

  • 2
    点赞
  • 2
    评论
  • 7
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值