资讯专栏INFORMATION COLUMN

java并发编程学习之线程的生命周期-wait,notify,notifyall(六)

Terry_Tai / 2906人阅读

摘要:不释放持有的锁,释放锁。在调用方法前,必须持有锁,调用唤醒,也要持有锁。休眠一定时间后,进入就绪状态。这两个都能被方法中断当前状态。用法方获取锁判断条件,不满足继续满足执行其他业务方获取锁改变条件通知为什么是而不是会一直循环,直到条件满足。

sleep和wait

sleep是Thread类的方法,wait是Object的方法。

sleep可以到处使用,wait必须是在同步方法或者代码块里使用,不然会有java.lang.IllegalMonitorStateException异常。

sleep不释放持有的锁,wait释放锁。wait在调用方法前,必须持有锁,调用notify,notifyall唤醒,也要持有锁。

sleep休眠一定时间后,进入就绪状态。wait由notify和notifyall唤醒。这两个都能被interrupt方法中断当前状态。

join和yield

这两个和sleep一样,不释放持有的锁。

示例
public class WaitDemo {
    private String tv = "广告";

    static class Tv extends Thread {
        WaitDemo waitDemo;

        public Tv(WaitDemo waitDemo) {
            this.waitDemo = waitDemo;
        }

        @Override
        public void run() {
            waitDemo.waitTv();
        }
    }

    public synchronized void waitTv() {
        while (tv.equals("广告")) {
            try {
                wait();
                if (tv.equals("广告")) {
                    System.out.println(Thread.currentThread().getName() + "-" + "骗人,还是广告");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + "-" +"愉快的追剧");
    }

    public synchronized void sendTrueMsg() {
        tv = "正剧";
        notifyAll();
    }

    public synchronized void sendFalseMsg() {
        notifyAll();
    }

    public static void main(String[] args) throws InterruptedException {
        WaitDemo waitDemo = new WaitDemo();
        Tv tv1 = new Tv(waitDemo);
        Tv tv2 = new Tv(waitDemo);
        tv1.start();
        tv2.start();
        Thread.sleep(100);
        waitDemo.sendFalseMsg();
        Thread.sleep(100);
        waitDemo.sendTrueMsg();
    }
}

运行的结果如下:

例子:大部分人喜欢看连续剧,但是不看广告(没钱买VIP),于是就让别人提醒她广告结束了没有,如果结束了,就提醒她。
用法:

wait方

获取锁

while判断条件,不满足继续wait

满足执行其他业务

notify方

获取锁

改变条件

通知

为什么是while而不是if

while会一直循环,直到条件满足。如果是if,只会判断一次,如果不满足条件,会一直等待

为什么是notifyAll而不是notify

可以把上面的例子,改成notify,那么进程永远不会结束,因为在多线程情况下,notify只能唤醒随机的一个休眠线程,其他已休眠的线程不能唤醒,造成信号不能传达而丢失,而notifyAll可以唤醒所有的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75252.html

相关文章

  • 一起并发编程 - 等待与通知

    摘要:如果有其它线程调用了相同对象的方法,那么处于该对象的等待池中的线程就会全部进入该对象的锁池中,从新争夺锁的拥有权。 wait,notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视,而本文则是对这些关键字的使用进行描述。 存在即合理 在java中,每个对象都有两个池,锁池(monitor)和等待池(waitset),每个...

    Meathill 评论0 收藏0
  • java并发编程习之线程生命周期-interrupt(七)

    摘要:和是配套使用的,方法容易导致死锁。方法不会保证线程的资源正常释放方法给线程打个停止标记,将线程的中断状态设置为,并没有马上强制中断线程,线程是否中断由线程自己决定。终结状态,还是返回。方法判断当前线程是否中断,清除中断标志。 resume、suspend、stop resume和suspend是配套使用的,suspend方法容易导致死锁。 stop方法不会保证线程的资源正常释放 i...

    maxmin 评论0 收藏0
  • Java并发总结

    摘要:限期阻塞调用方法等待时间结束或线程执行完毕。终止状态线程执行完毕或出现异常退了。和都会检查线程何时中断,并且在发现中断时提前放回。工厂方法将线程池的最大大小设置为,而将基本大小设置为,并将超时大小设置为分钟。 wait()、notify()、notifyAll() Object是所有类的基类,它有5个方法组成了等待、通知机制的核心:notify()、notifyAll()、wait()...

    szysky 评论0 收藏0
  • java并发编程习之线程生命周期(一)

    摘要:就绪状态调用或者由阻塞状态被解除时,进入就绪状态,此时,只能表示线程可以运行了,但不代表已经运行了,需要等待的调度。死亡状态当线程执行结束或者异常等,线程就会结束,进入死亡状态。 流程图 showImg(https://segmentfault.com/img/bVbuJ6f); 新建状态 当用new创建一个线程后,线程就处于新建状态,此时和其他普通java对象一样,由JVM创建内存空...

    AndroidTraveler 评论0 收藏0
  • Java线程习(四)等待/通知(wait/notify)机制

    摘要:运行可运行状态的线程获得了时间片,执行程序代码。阻塞的情况分三种一等待阻塞运行的线程执行方法,会把该线程放入等待队列中。死亡线程方法执行结束,或者因异常退出了方法,则该线程结束生命周期。死亡的线程不可再次复生。 系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键...

    PiscesYE 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<