wait()、notify()和notityALL()

wait()、notify()和notityALL()

wait方法是Object中的方法,这个方法的功能特性:
1).执行wait方法的前提是当前线程已经获取到对象的锁,也就是wait方法必须在synchronized修饰的代码块或者方法中使用。 
2).执行wait之后,当前线程会失去锁的所有权,并暂停执行,一直等待,直到其他线程调用notify()、notifyAll()把其唤醒或者所在线程被中断
3).被notify()或者notifyAll()唤醒后,wait线程并不会立即开始继续执行,wait线程还是会等待,直到拥有锁的所有权,才会继续往下执行。

notify、notifyAll
notify已经在上面有提到过,notify和notifyAll 的作用是唤醒正在wait的线程,notify是**随机唤醒**wait线程中的一个,notifyAll 则是唤醒全部。
1).执行notify、notifyAll 方法的前提是当前线程已经获取到对象的锁,也就是必须在synchronized修饰的代码块或者方法中使用。这个和wait是一样的。 
2).之前wait的线程被notify()或者notifyAll()唤醒后,wait线程还是会继续等待,直到拥有锁的所有权,wait线程才会继续往下执行。 
3).调用notify、notifyAll不会释放锁,而是等待代码块执行完之后才释放锁,这个与wait不同。

如下几个例子来说明他们的使用:
例子一:
public static void main(String[] args) throws InterruptedException {
        Object lock1 = new Object();
        Thread t1 = new Thread(new Test().new Tt1(lock1));
        Thread t2 = new Thread(new Test().new Tt2(lock1));
        t1.start();
        Thread.sleep(1000);
        t2.start();
    }


    class Tt1 implements Runnable{

        private Object lock1;

        public Tt1(Object lock1) {
            this.lock1 = lock1;
        }

        @Override
        public void run() {
            try {
                System.out.println(this.getClass()+"-------1");
                synchronized (lock1) {
                    Thread.sleep(2000);
                    System.out.println("waiting start");
                    lock1.wait();
                }
                System.out.println("waiting end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class Tt2 implements Runnable{

        private Object lock1;

        public Tt2(Object lock1) {
            this.lock1 = lock1;
        }

        @Override
        public void run() {
            System.out.println(this.getClass()+"-------1");
            synchronized (lock1) {
                try {
                    System.out.println(this.getClass()+"-------2");
                    lock1.notify();
                    Thread.sleep(1000);
                    System.out.println(this.getClass()+"-------3");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }
执行结果:

class Test$Tt1-------1
class Test$Tt2-------1
waiting start
class Test$Tt2-------2
class Test$Tt2-------3
waiting end

分析一下: 
第1、2行:t1和t2启动,t1先获取到锁所以t1先执行,t2一直被阻塞住 
第3、4行:t1中执行了wait,所以锁被释放,t1暂停执行,处于等待状态,t2获取锁并开始执行。 
第5、6行:t2中调用了notify()唤醒t1,但是t2并不会释放锁所以t1没有马上执行,因为锁现在是被t2拥有,等t2执行完成释放锁后,t1继续执行。


例子二:
public static void main(String[] args) throws InterruptedException {
        Object lock1 = new Object();
        Thread t1 = new Thread(new Test().new Tt1(lock1));
        Thread t2 = new Thread(new Test().new Tt2(lock1));
        t1.start();
        Thread.sleep(100);
        t2.start();
    }

    class Tt1 implements Runnable{
        private Object lock1;

        public Tt1(Object lock1) {
            this.lock1 = lock1;
        }

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

    class Tt2 implements Runnable{

        private Object lock1;

        public Tt2(Object lock1) {
            this.lock1 = lock1;
        }

        @Override
        public void run() {
            synchronized (lock1) {
                try {
                    System.out.println(Thread.currentThread().getName()+"---start");
                    System.out.println(Thread.currentThread().getName()+"---end");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }
运行结果:
Thread-0---start
Thread-1---start
Thread-1---end
Thread-0执行wait后马上释放了锁,所以Thread-1很快接着就执行,但是Thread-0没有被唤醒,所以Thread-0就终止运行了。


例子三:
public static void main(String[] args) throws InterruptedException {
        Object lock1 = new Object();
        Thread t1 = new Thread(new Test().new Tt1(lock1));
        Thread t2 = new Thread(new Test().new Tt2(lock1));
        t1.start();
        Thread.sleep(100);
        t2.start();
    }

    class Tt1 implements Runnable{
        private Object lock1;

        public Tt1(Object lock1) {
            this.lock1 = lock1;
        }

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

    class Tt2 implements Runnable{

        private Object lock1;

        public Tt2(Object lock1) {
            this.lock1 = lock1;
        }

        @Override
        public void run() {
            synchronized (lock1) {
                try {
                    System.out.println(Thread.currentThread().getName()+"---start");
                    System.out.println(Thread.currentThread().getName()+"---end");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }
--------------------- 
执行结果:

Thread-0---start
Thread-0---end
Thread-1---start
Thread-1---end

可见Thread-0在执行nofity后并没有释放锁,而是等待代码块执行完之后才释放锁,Thread-1才能继续执行。

例子四:
wait()遇到interrupt()
之前说道interrupt(),并不会直接中断线程,而是会给线程一个中断标志,而且包括sleep、wait、join会抛出InterruptedException。
public static void main(String[] args) throws InterruptedException {
            Object lock1 = new Object();
            Thread t1 = new Thread(new Test().new Tt1(lock1));
            t1.start();
            Thread.sleep(100);
            t1.interrupt();
        }

        class Tt1 implements Runnable{
            private Object lock1;

            public Tt1(Object lock1) {
                this.lock1 = lock1;
            }

            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        System.out.println(Thread.currentThread().getName()+"---start");
                        lock1.wait();
                        System.out.println(Thread.currentThread().getName()+"---end");
                    }catch (InterruptedException e) {
                        System.out.println("线程被中断了");;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
--------------------- 
执行结果:

Thread-0---start
线程被中断了


例子五:
notifyAll和nofity唯一的不同就是,可以唤醒全部和唤醒一个, 先举个nofity的例子
public static void main(String[] args) throws InterruptedException {
            Object lock1 = new Object();
            Thread t1 = new Thread(new Test().new Tt1(lock1));
            Thread t2 = new Thread(new Test().new Tt1(lock1));
            Thread t3 = new Thread(new Test().new Tt2(lock1));
            t1.start();
            Thread.sleep(100);
            t2.start();
            Thread.sleep(100);
            t3.start();
        }

        class Tt1 implements Runnable{
            private Object lock1;

            public Tt1(Object lock1) {
                this.lock1 = lock1;
            }

            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        System.out.println(Thread.currentThread().getName()+"---start");
                        System.out.println(Thread.currentThread().getName()+"---wait");
                        lock1.wait();
                        System.out.println(Thread.currentThread().getName()+"---end");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        class Tt2 implements Runnable{

            private Object lock1;

            public Tt2(Object lock1) {
                this.lock1 = lock1;
            }

            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        System.out.println(Thread.currentThread().getName()+"---start");
                        System.out.println(Thread.currentThread().getName()+"---notify");
                        lock1.notify();
                        System.out.println(Thread.currentThread().getName()+"---end");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        }
--------------------- 
执行结果:

Thread-0---start
Thread-0---wait
Thread-1---start
Thread-1---wait
Thread-2---start
Thread-2---notify
Thread-2---end
Thread-0---end

Thread-0和Thread-1在wait,Thread-2执行了notify,但只有Thread-0被唤醒,重新开始执行,Thread-1还在wait。


例子六:
public static void main(String[] args) throws InterruptedException {
            Object lock1 = new Object();
            Thread t1 = new Thread(new Test().new Tt1(lock1));
            Thread t2 = new Thread(new Test().new Tt1(lock1));
            Thread t3 = new Thread(new Test().new Tt2(lock1));
            t1.start();
            Thread.sleep(100);
            t2.start();
            Thread.sleep(100);
            t3.start();
        }

        class Tt1 implements Runnable{
            private Object lock1;

            public Tt1(Object lock1) {
                this.lock1 = lock1;
            }

            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        System.out.println(Thread.currentThread().getName()+"---start");
                        System.out.println(Thread.currentThread().getName()+"---wait");
                        lock1.wait();
                        System.out.println(Thread.currentThread().getName()+"---end");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        class Tt2 implements Runnable{

            private Object lock1;

            public Tt2(Object lock1) {
                this.lock1 = lock1;
            }

            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        System.out.println(Thread.currentThread().getName()+"---start");
                        System.out.println(Thread.currentThread().getName()+"---notifyAll");
                        lock1.notifyAll();
                        System.out.println(Thread.currentThread().getName()+"---end");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        }
--------------------- 
执行结果:

Thread-0---start
Thread-0---wait
Thread-1---start
Thread-1---wait
Thread-2---start
Thread-2---notifyAll
Thread-2---end
Thread-1---end
Thread-0---end

Thread-2执行了notifyAll后,Thread-1和Thread-0都被唤醒。在Thread-2执行完成之后,Thread-1和Thread-0都会分别继续执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值