范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

如何优雅地停下线程?除了这两种,你还能说出一种算我输

  前言
  今天主要来聊一聊如何优雅地停下线程。
  在开始之前,我们可以思考一下,如何能够让线程停下?
  通过查阅JDK,我们不难发现Thread为我们提供了一个stop方法,只要使用stop方法,就立即停止线程,但是发现stop()方法被标注为废弃的方法,因为这个方法会强行把执行到一半的线程终止,可能会引发一些数据不一致或者我们没发预估的问题。
  除了stop()方法,我能想到的方案还有两个,
  方案一:使用volatile标记位,利用其可见性
  方案二:调用Thread的方法interrupted方案实现方案一:使用volatile标记位,利用其可见性
  通过代码我们来看下方案一,这是一个很经典的生产者和消费者模式。
  生产者Demo//生产者 class Producer implements Runnable {     public volatile boolean canc = false;      private Product product;      Producer(Product product) {         this.product = product;     }      @Override     public void run() {         try {             while (!canc) {                 try {                     //Thread.sleep(1000);                     product.put("iphone6s");                     System.out.println("put:" + Thread.currentThread().getName());                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }         } catch (Exception ex) {             ...         } finally {             System.out.println("结束");         }     } }
  消费者Demo//消费者 class Consumer implements  Runnable{     private Product product;      Consumer(Product product) {         this.product = product;     }      @Override     public void run() {         while (Math.random() > 0.9){             try {                 Thread.sleep(1000);                 product.take("iPhone6s");                 System.out.println("take:"+Thread.currentThread().getName());             } catch (InterruptedException e) {                 e.printStackTrace();             }         }     } }
  调用生产者和消费者public static void main(String[] args) {     ArrayBlockingQueue queue = new ArrayBlockingQueue(1);     Product product = new Product(queue);     Producer producer = new Producer(product);     Consumer consumer = new Consumer(product);     Thread c1 = new Thread(consumer);     Thread p1 = new Thread(producer);     p1.start();     try {         Thread.sleep(500);     } catch (InterruptedException e) {         e.printStackTrace();     }     c1.start();     System.out.println("消费者不需要更多数据了。");     producer.canc = true;     System.out.println(producer.canc);     System.out.println(p1.getState()); }
  场景一: 我们把消费者和生产者的线程都开起来,生产者生产一个产品,消费者都会消费一个产品,这个时候volatile的值,在下一次的轮询中值已经变成了true,就跳出while循环,线程就停止,这个场景下volatile就适用了。
  场景二: 我们将消费者线程不启动,只生产不消费。 理论上我们期待的结果应该也是值变成true,跳出while循环,线程停止。
  结果打印:Put a iphone6s put:Thread-2 消费者不需要更多数据了。 valatile的值: true 线程状态:WAITING
  根据打印的结果我们会观察到他没有输出结束的语句,
  我们看到了生产者生产了产品,valatile也修改了值,但是线程却没有结束,
  这主要的原因是因为,生产者执行了product.put("iphone6s"),没有被消费,造成了阻塞,在它唤醒之前,
  无法进入下一次的轮询判断。造成了值修改了,却没有做出相应处理。
  我们发现在消费的时候,take方法内部会触发唤醒,当检测到线程已经停止,则抛出InterruptedException异常。开源码说话,可以看到dequeue,唤醒了线程。public E take() throws InterruptedException {     final ReentrantLock lock = this.lock;     lock.lockInterruptibly();     try {         while (count == 0)             notEmpty.await();         return dequeue();     } finally {         lock.unlock();     } }  public final void acquireInterruptibly(int arg)         throws InterruptedException {     if (Thread.interrupted())         throw new InterruptedException(); }  private E dequeue() {     ...     //释放     notFull.signal();     return x; } 二、方案二:调用Thread的方法interruptedstatic class CreateRunable implements Runnable {     public CreateRunable(int i) {         this.i = i;     }      private int i;      public int getI() {         return i;     }      public void setI(int i) {         this.i = i;     }      @Override     public  void run() {         synchronized (this){             while ( !Thread.currentThread().isInterrupted() ){                 System.out.println("Runable接口,实现线程"+i++);             }         }     } }Thread createThread = new Thread(new CreateRunable(0)); createThread.start(); Thread.sleep(5); createThread.interrupt();
  休眠5毫秒后,该线程检查到了中断信号,就会停止线程。
  那如果任务正在休眠状态,线程会如何处理呢@Override public  void run() {     synchronized (this){         while ( !Thread.currentThread().isInterrupted() ){             try {                 Thread.sleep(10000);             } catch (InterruptedException e) {                 e.printStackTrace();             }             System.out.println("Runable接口,实现线程"+i++);         }     } }
  抛出异常,同时清除中断状态,线程会继续执行Runable接口,实现线程0 java.lang.InterruptedException: sleep interrupted     at java.lang.Thread.sleep(Native Method)     at main.Thread.threadStartThreeWays$CreateRunable.run(threadStartThreeWays.java:48)     at java.lang.Thread.run(Thread.java:748) Runable接口,实现线程1 Runable接口,实现线程2 Runable接口,实现线程3 总结
  我们在这里就不说Stop()方法,因为他太暴力了,不够优雅。这里的优雅指的是可以让线程有时间做好收尾工作,避免数据的错乱。 优雅停下线程的方式主要有两种方案一:使用volatile标记位。方案二:调用Thread的方法interrupted。
  通过上面的demo案例,我们可以看到使用方案一的volatile,在某一些特殊的场景下,会发生不能关闭线程的情况。
  所以volatile是不够全面的。方案二则是一种更优的选择。

仅有12万人的城市,城市面积狭小,酒店宾馆却多达100家我国每个城市都有自己独特的魅力,有的城市以名人著称,有的城市则以美食著称,当然也有以景色著称的城市,在四川有一个仅有12万人的城市,却一直是很多自驾游朋友的必去的地方,这个城市就是帕米尔高原,古称葱岭不周山喀什塔什库尔干塔吉克自驾游(22)帕米尔高原,古称不周山,后称葱岭(西游记里的葱岭),十万平方公里,中国,阿富汗,塔吉克斯坦三国各占一块。古丝绸之路中线,南线在此汇合,汇合地石头城,即塔什库尔干塔吉克自治县(简称塔去西藏旅游,看到穷游女在布达拉宫前倒了一瓶水,是怎么回事?西藏地处我国的西南,虽然交通不方便,经济不发达,但是仍然阻挡不了大家对于西藏美景的追求,挡不住大家对于去西藏净化心灵的向往。可能也正是因为这种闭塞,所以才造就了西藏的淳朴与自然。尤昆仑山脉赞昆仑山脉是世界山脉的始祖,又称万山之祖,地跨青海四川新疆和西藏四个省份,全长2500千米,也是亚洲最长的山脉,被称为亚洲脊柱,与秦岭山脉几乎在同一线上。昆仑山脉神奇神幻,承载着大半大唐不夜城中国符号的践行者大唐不夜城太火了,灯光烟火气息浓郁。新的城市文化,新的中国特色文创,吸引了大批的游客,唐朝文化里独有的艺术魅力在发掘中不断发展,唐装,汉服,灯光节,玲珑夜市掀起新的风潮。下面就带你万里长城(中国的世界遗产)长城西起嘉峪关,东至鸭绿江。途经甘肃宁夏陕西山西内蒙古河北北京天津辽宁等九个省市自治区。它是沿着不同的地形山脉和地貌建造的。长城是由烽火台和列城等单体建筑发展起来的。第一种是烽火台各省标志性美景,下次去玩就不会找不到地方了!你去过几个?你是否想游览祖国大好河山想来一场说走就走的旅行却不知该去哪里现在就告诉大家各省美景让你随时说走就走河北山海关山海关山海关,又称榆关渝关临闾关,位于河北省秦皇岛市东北15千米处,是明她急眼了,十个小时不到地铁运营公司就隔空喊话快把票还给我文章为唐sir骑马探世界原创,版权归作者所有,欢迎个人分享转载。导语踏遍万水千山,寻遍世间美景,关注唐sir,你的旅途将不再孤单,带你游遍大千世界,看尽世间趣闻乐事。不知道大家有没大海为什么会涨潮退潮?退潮的海水难道消失了吗?到底去哪了?大海向来是美丽而危险的,它会给人类带来丰富的海产品,但也能随时将人拉下海底。随着时代的不断发展,我们的生存需求得到了基本保障,也就开始追求起了精神上的享受,其中有很多人喜欢去海边玩芬兰小众宝藏玻璃屋面朝大海拥抱极光概述疫情当下,依然挡不住海外追光客对极光和玻璃屋的热情,不少宝宝私信我疫情中玻璃屋依然很火爆有些居然订不上怎么办?今天来跟大家分享一家极为小众但又十分宝藏的玻璃屋。连冰岛总统都前来不输贝加尔湖!国内最新天空之境,人少景美,还免费去什么贝加尔湖啊来普莫雍错吧冰封300平方公里人间仙境冬天,去贝加尔湖看蓝冰已经成了很多人的一种向往。但是如今因为疫情,大家的向往也变成了遥遥无期,不免有些遗憾。可很多人都不知道,
2岁宝宝患痔疮,竟是因为错误的喂养方式2岁的峰峰是家里的宝贝,长得却比较矮小,加上峰峰父母身高都不算高,家里人很烦愁。为了不让孩子输在起跑线上,峰峰妈决定要加强给孩子补充好营养,每天给峰峰精心准备各种食物,还把钙片碾碎天才陨落还是重生?场均2817科比收他做门徒!如今打夏联都费劲夏季联赛首场较量,洛杉矶湖人队取得一场大胜,名宿大鲨鱼奥尼尔之子谢里夫奥尼尔完成了NBA生涯的首秀。虽然身披湖人战袍,但完全看不出谢里夫有任何当年父亲驰骋赛场的身影。作为落选秀的他讲了一个月的睡前故事,宝宝变化太大了家有26岁的娃要知道大家好,我是果妈在果妈的印象中,睡前故事,就是哄娃睡觉的。但是在当了妈,深究育儿之后才知道睡前故事的作用,原来不只是哄睡!而且利用好睡前故事,对宝宝来说,就是一个非常高效的早教方式四川担担面那么好吃,为何没能火遍全国?4个短板限制其发展遍布四川的担担面,为何在全国火不起来?员工4个短板赶走了顾客中国很大,每个地区都有各自的特色美食,作为一个吃货,最想去的旅游之地,便是美食遍地的四川,说到四川的美食很多人都会想起享去河北必点的6道冀菜,是冀菜之魂,老板以为你是河北人要是去过河北,就知道当地的景色有多迷人了。河北的美景让人流连忘返,河北的美食更是挑战人的味蕾。要是爱吃美食,河北绝对是一个非常不错的地方,在这里,你想吃的都可以找到。要是来了河北,中国第一个要消失的沙漠面积比海南岛还大,如今80沙漠成绿洲一望无际的沙漠被称作生命的禁区。在中国广袤的国土上,有着为数不少的沙漠地带,那里虽然曾经是绿洲草场,自然环境良好,有着辉煌灿烂的历史文化但是,随着滚滚黄沙的侵袭,加之人为的破坏,曾内蒙古自治区5A级旅游景区内蒙古自治区(简称内蒙古),位于祖国北部边疆,横跨东北华北西北地区,内与黑龙江吉林辽宁河北山西陕西宁夏甘肃8省区相邻,外与俄罗斯蒙古国接壤,是中华人民共和国省级行政区,面积118。你过去了吗北海涠洲岛五彩滩五海滩,位于涠洲岛东海岸,这里主要是贝壳和火山石磨细成的黑沙石,海岸边是陡峭的海蚀崖,走下沙滩不远就是是岛上面积最大的海蚀平台。(图片来源于网络)据说退潮时可见宽达几十米至上百米的周末不知去哪玩,快来十渡乐谷银滩炎炎夏日,如果不知道周末去哪玩,我建议你可以开车直接奔十渡,无论你是进景区,还是沿拒马河,钓鱼,戏水,露营,还是去六渡马场纵马扬鞭。在这青山绿水之间,都是无边的快乐。今天出来有点晚羽毛球经验笔记十六种小技巧与经验总结,非常适合业余球友学习羽毛球经验笔记十六种小技巧与经验总结,非常适合业余球友学习,经验如下一力争在身体前上方击球,千万不要让球落至颈部以下高度,否则回击的球就没有攻击力。二握拍手尽可能保持放松,以便最大复盘中澳世预赛跟体能没关系!中国男篮的防守导向是错误的图周琦本场被严防,只得到5分8板原本有机会创造历史,中国男篮距离首次击败澳大利亚只差10分钟的韧劲,甚至确切地说,是被瞬间拉开比分足以摧毁中国男篮自信心的那一分多钟。中国和澳大利亚