当前位置: 首页 > news >正文

网站搜索引擎提交西安seo顾问

网站搜索引擎提交,西安seo顾问,贵阳网站建设培训班,深圳app搭建sleep/wait/notify/notifyAll分别有什么作用#xff1f;它们的区别是什么#xff1f;wait时为什么要放在循环里而不能直接用if#xff1f;简介首先对几个相关的方法做个简单解释#xff0c;Object中有几个用于线程同步的方法#xff1a;wait、notify、notifyAll。public c…sleep/wait/notify/notifyAll分别有什么作用它们的区别是什么wait时为什么要放在循环里而不能直接用if简介首先对几个相关的方法做个简单解释Object中有几个用于线程同步的方法wait、notify、notifyAll。public class Object { public final native void wait(long timeout) throws InterruptedException; public final native void notify(); public final native void notifyAll();}wait: 释放当前锁阻塞直到被notify或notifyAll唤醒或者超时或者线程被中断(InterruptedException)notify: 任意选择一个(无法控制选哪个)正在这个对象上等待的线程把它唤醒其它线程依然在等待被唤醒notifyAll: 唤醒所有线程让它们去竞争不过也只有一个能抢到锁sleep: 不是Object中的方法而是Thread类的静态方法让当前线程持有锁阻塞指定时间sleep和waitsleep和wait都可以让线程阻塞也都可以指定超时时间甚至还都会抛出中断异常InterruptedException。而它们最大的区别就在于sleep时线程依然持有锁别人无法进当前同步方法wait时放弃了持有的锁其它线程有机会进入该同步方法。多次提到同步方法因为wait必须在synchronized同步代码块中否则会抛出异常IllegalMonitorStateExceptionnotify也是如此可以说wait和notify是就是为了在同步代码中做线程调度而生的。下面一个简单的例子展现sleep和wait的区别import java.util.Date;import java.util.concurrent.atomic.AtomicInteger;public class Main { // 日志行号记录 private AtomicInteger count new AtomicInteger(); public static void main(String[] args) throws InterruptedException { Main main new Main(); // 开启两个线程去执行test方法 new Thread(main::test).start(); new Thread(main::test).start(); } private synchronized void test() { try { log(进入了同步方法并开始睡觉1s); // sleep不会释放锁因此其他线程不能进入这个方法 Thread.sleep(1000); log(睡好了但没事做有事叫我等待2s); //阻塞在此并且释放锁其它线程可以进入这个方法 //当其它线程调用此对象的notify或者notifyAll时才有机会停止阻塞 //就算没有人notify如果超时了也会停止阻塞 wait(2000); log(我要走了但我要再睡一觉10s); //这里睡的时间很长因为没有释放锁其它线程就算wait超时了也无法继续执行 Thread.sleep(10000); log(走了); notify(); } catch (InterruptedException e) { e.printStackTrace(); } } // 打印日志 private void log(String s) { System.out.println(count.incrementAndGet() new Date().toString().split( )[3] Thread.currentThread().getName() s); }}/* 输出:1 00:13:23Thread-0 进入了同步方法并开始睡觉1s2 00:13:24Thread-0 睡好了但没事做有事叫我等待2s3 00:13:24Thread-1 进入了同步方法并开始睡觉1s4 00:13:25Thread-1 睡好了但没事做有事叫我等待2s5 00:13:26Thread-0 我要走了但我要再睡一觉10s6 00:13:36Thread-0 走了7 00:13:36Thread-1 我要走了但我要再睡一觉10s8 00:13:46Thread-1 走了*/对输出做个简单解释(已经看懂代码的童鞋可以跳过)1 00:13:23Thread-0 进入了同步方法并开始睡觉1s // Thread-0首先进入同步方法Thread-1只能门外候着2 00:13:24Thread-0 睡好了但没事做有事叫我等待2s // Thread-0 sleep 1秒这段时间Thread-1没进来证明sleep没有释放锁3 00:13:24Thread-1 进入了同步方法并开始睡觉1s // Thread-0开始wait后Thread-1马上就进来了证明wait释放了锁4 00:13:25Thread-1 睡好了但没事做有事叫我等待2s // Thread-1也打算wait 2秒(2秒后真的能醒来吗)5 00:13:26Thread-0 我要走了但我要再睡一觉10s // Thread-0已经wait超时醒来了这次准备sleep 10s6 00:13:36Thread-0 走了 // 10s过去了Thread-0都sleep结束了那个说要wait 2s的Thread-1还没动静证明超时也没用还得抢到锁7 00:13:36Thread-1 我要走了但我要再睡一觉10s // Thread-0退出同步代码后Thread-1才终于得到了锁能行动了8 00:13:46Thread-1 走了notify和notifyAll同样是唤醒等待的线程同样最多只有一个线程能获得锁同样不能控制哪个线程获得锁。区别在于notify唤醒一个线程其他线程依然处于wait的等待唤醒状态如果被唤醒的线程结束时没调用notify其他线程就永远没人去唤醒只能等待超时或者被中断notifyAll所有线程退出wait的状态开始竞争锁但只有一个线程能抢到这个线程执行完后其他线程又会有一个幸运儿脱颖而出得到锁如果觉得解释的不够明白代码来一波import java.util.Date;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.atomic.AtomicInteger;public class Main { private AtomicInteger count new AtomicInteger(); public static void main(String[] args) throws InterruptedException { Main main new Main(); // 开启两个线程去执行test方法 for (int i 0; i 10; i) { new Thread(main::testWait).start(); } Thread.sleep(1000); for (int i 0; i 5; i) { main.testNotify(); } } private synchronized void testWait() { try { log(进入了同步方法开始wait); wait(); log(wait结束); } catch (InterruptedException e) { e.printStackTrace(); } } private synchronized void testNotify() { notify(); } private void log(String s) { System.out.println(count.incrementAndGet() new Date().toString().split( )[3] Thread.currentThread().getName() s); }}/* 输出:1 00:59:32Thread-0 进入了同步方法开始wait2 00:59:32Thread-9 进入了同步方法开始wait3 00:59:32Thread-8 进入了同步方法开始wait4 00:59:32Thread-7 进入了同步方法开始wait5 00:59:32Thread-6 进入了同步方法开始wait6 00:59:32Thread-5 进入了同步方法开始wait7 00:59:32Thread-4 进入了同步方法开始wait8 00:59:32Thread-3 进入了同步方法开始wait9 00:59:32Thread-2 进入了同步方法开始wait10 00:59:32Thread-1 进入了同步方法开始wait11 00:59:33Thread-0 wait结束12 00:59:33Thread-6 wait结束13 00:59:33Thread-7 wait结束14 00:59:33Thread-8 wait结束15 00:59:33Thread-9 wait结束*/例子中有10个线程在wait但notify了5次然后其它线程一直阻塞这也就说明使用notify时如果不能准确控制和wait的线程数对应可能会导致某些线程永远阻塞。使用notifyAll唤醒所有等待的线程import java.util.Date;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.atomic.AtomicInteger;public class Main { private AtomicInteger count new AtomicInteger(); public static void main(String[] args) throws InterruptedException { Main main new Main(); // 开启两个线程去执行test方法 for (int i 0; i 5; i) { new Thread(main::testWait).start(); } Thread.sleep(1000); main.testNotifyAll(); } private synchronized void testWait() { try { log(进入了同步方法开始wait); wait(); log(wait结束); } catch (InterruptedException e) { e.printStackTrace(); } } private synchronized void testNotifyAll() { notifyAll(); } private void log(String s) { System.out.println(count.incrementAndGet() new Date().toString().split( )[3] Thread.currentThread().getName() s); }}/* 输出:1 01:03:24Thread-0 进入了同步方法开始wait2 01:03:24Thread-4 进入了同步方法开始wait3 01:03:24Thread-3 进入了同步方法开始wait4 01:03:24Thread-2 进入了同步方法开始wait5 01:03:24Thread-1 进入了同步方法开始wait6 01:03:25Thread-1 wait结束7 01:03:25Thread-2 wait结束8 01:03:25Thread-3 wait结束9 01:03:25Thread-4 wait结束10 01:03:25Thread-0 wait结束*/只需要调用一次notifyAll所有的等待线程都被唤醒并且去竞争锁然后依次(无序)获取锁完成了后续任务。为什么wait要放到循环中使用一些源码中出现wait时往往都是伴随着一个循环语句出现的比如private synchronized void f() throws InterruptedException { while (!isOk()) { wait(); } System.out.println(Im ok);}既然wait会被阻塞直到被唤醒那么用ifwait不就可以了吗其他线程发现条件达到时notify一下不就行了理想情况确实如此但实际开发中我们往往不能保证这个线程被notify时条件已经满足了因为很可能有某个无关(和这个条件的逻辑无关)的线程因为需要线程调度而调用了notify或者notifyAll。此时如果样例中位置等待的线程不巧被唤醒它就会继续往下执行但因为用的if这次被唤醒就不会再判断条件是否满足最终程序按照我们不期望的方式执行下去。
http://www.zqtcl.cn/news/348742/

相关文章:

  • 韩国网页设计公司网站有经验的大良网站建设
  • 游戏币网站怎么做十堰电商网站建设
  • 旅游网站系统哪个好城市建设投资公司网站
  • 制作图片海报的软件关键词seo公司
  • 济南企业网站推广方法wordpress 类别 排序
  • 深圳网站建设开发公司哪家好wordpress 删除主题作者
  • 网站怎么登陆后台wordpress卡蜜 插件
  • wordpress安装微信登录插件青岛网站seo技巧
  • 燕郊个人做网站超变传奇手游刀刀切割无会员散人
  • 有没有可以做兼职的网站网站建设发展方向有哪些
  • php网站后台上传图片有没有推荐到首页的功能客户求购平台
  • 大型网站的标准莱芜市官网
  • 建站用Wordpress还是青州网站建设青州
  • 百度网站收录更新建网站的公司赚钱吗
  • 哪种语言做网站最快网站大全app下载
  • 手机营销网站制作网站建设备案和免备案的区别
  • 浙江省住房和城乡建设厅网站打不开中国建设银行官网站纪念币预约
  • 推广软件的网站安徽省城乡建设网站
  • 用网站做淘宝客怎么样珍爱网
  • 龙岩建设局招聘网站网站dns解析失败
  • 音乐网站的音乐怎么做深圳美容网站建设
  • 贵阳市观山湖区网站建设wordpress博客vieu模板
  • 怎么区分网站的好坏网站建设营销型号的区别
  • wordpress固定链接 中文建设网站优化
  • 东莞地产网站建设简述建设iis网站的基本过程
  • 外贸网站建设 公司价格怎样在手机上制作网站
  • 网站建设电话销售录音企业做网站有什么用
  • 网站布局设计软件软件工程大学排名
  • 自己的网站做防伪码深圳软件开发公司招聘
  • 网上购物网站大全wordpress文本悬停变色