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

超详细的线程池使用解析

  前言
  Java 中线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池。合理的使用线程池可以带来多个好处:
  (1)降低资源消耗。通过重复利用已创建的线程降低线程在创建和销毁时造成的消耗。
  (2)提高响应速度。当处理执行任务时,任务可以不需要等待线程的创建就能立刻执行。
  (3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。1、线程池的实现原理
  线程池的处理流程如上图所示
  线程池中通过 ctl 字段来表示线程池中的当前状态,主池控制状态 ctl 是 AtomicInteger 类型,包装了两个概念字段:workerCount 和 runState,workerCount 表示有效线程数,runState 表示是否正在运行、正在关闭等状态。使用 ctl 字段表示两个概念,ctl 的前 3 位表示线程池状态,线程池中限制 workerCount 为(2^29 )-1(约 5 亿)个线程,而不是 (2^31)-1(20 亿)个线程。workerCount 是允许启动和不允许停止的工作程序的数量。该值可能与实际的活动线程数暂时不同,例如,当 ThreadFactory 在被询问时未能创建线程时,以及退出线程在终止前仍在执行记时。用户可见的池大小报告为工作集的当前大小。 runState 提供主要的生命周期控制,取值如下表所示:
  字段名
  含义
  RUNNING
  接受新任务并处理排队任务
  SHUTDOWN
  不接受新任务,但处理排队任务
  STOP
  不接受新任务,不处理排队任务,并中断正在进行的任务
  TIDYING
  所有任务都已终止,workerCount 为零,转换到状态 TIDYING 的线程将运行 terminate() 方法
  TERMINATED
  terminate() 方法执行完成
  runState 随着时间的推移而改变,在 awaitTermination() 方法中等待的线程将在状态达到 TERMINATED 时返回。状态的转换为:
  RUNNING -> SHUTDOWN 在调用 shutdown() 时,可能隐含在 finalize() 中
  (RUNNING 或 SHUTDOWN)-> STOP 在调用 shutdownNow() 时
  SHUTDOWN -> TIDYING 当队列和线程池都为空时
  STOP -> TIDYING 当线程池为空时
  TIDYING -> TERMINATED 当 terminate() 方法完成时
  开发人员如果需要在线程池变为 TIDYING 状态时进行相应的处理,可以通过重载 terminated() 函数来实现。
  结合上图说明线程池 ThreadPoolExecutor 执行流程,使用 execute() 方法提交任务到线程池中执行时分为4种场景:
  (1)线程池中运行的线程数量小于 corePoolSize,创建新线程来执行任务。
  (2)线程池中运行线程数量不小于 corePoolSize,将任务加入到阻塞队列 BlockingQueue。
  (3)如果无法将任务加入到阻塞队列(队列已满),创建新的线程来处理任务(这里需要获取全局锁)。
  (4)当创建新的线程数量使线程池中当前运行线程数量超过 maximumPoolSize,线程池中拒绝任务,调用 RejectedExecutionHandler.rejectedExecution() 方法处理。
  源码分析:public void execute(Runnable command) {   if (command == null)     throw new NullPointerException();   int c = ctl.get();   //如果线程数小于基本线程数,创建线程执行   if (workerCountOf(c) < corePoolSize) {     if (addWorker(command, true))       return;     c = ctl.get();   }   //如果线程数不小于基本线程数,将任务添加到队列中   if (isRunning(c) && workQueue.offer(command)) {     int recheck = ctl.get();     if (! isRunning(recheck) && remove(command))       reject(command);     else if (workerCountOf(recheck) == 0)       addWorker(null, false);   }   //如果队列已满,创建新的线程去处理   else if (!addWorker(command, false))     //执行拒绝策略     reject(command); }	 复制代码
  线程池创建线程时,会将线程封装成工作线程 Worker,Worker 在执行完任务后,还会循环获取工作队列里的任务来执行。2、线程池的创建和使用创建线程池
  创建线程池之前,首先要知道创建线程池中的核心参数:
  corePoolSize(核心线程数大小):当提交任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,直到需要执行的任务数大于核心线程数时就不再创建。
  runnableTaskQueue(任务队列):用于保存等待执行任务的阻塞队列。一般选择以下几种:
  ArrayBlockingQueue:基于数组的有界阻塞队列,按照 FIFO 原则对元素进行排序。
  LinkedBlockingQueue:基于链表的阻塞队列,按照 FIFO 原则对元素进行排序。
  SynchronousQueue:同步阻塞队列,也是不存储元素的阻塞队列。每一个插入操作必须要等到另一个 线程调用移除操作,否则插入操作一直处于阻塞状态。
  PriorityBlockingQueue:优先阻塞队列,一个具有优先级的无限阻塞队列。
  maximumPoolSize(最大线程数大小):线程池允许创建的最大线程数,当队列已满,并且线程池中的线程数小于最大线程数,则线程池会创建新的线程执行任务。当使用无界队列时,此参数无用。
  RejectedExecutionHandler(拒绝策略):当任务队列和线程池都满了,说明线程池处于饱和状态,那么必须使用拒绝策略来处理新提交的任务。JDK 内置拒绝策略有以下 4 种:
  AbortPolicy:直接抛出异常
  CallerRunsPolicy:使用调用者所在的线程来执行任务
  DiscardOldestPolicy:丢弃队列中最近的一个任务来执行当前任务
  DiscardPolicy:直接丢弃不处理
  可以根据应用场景来实现 RejectedExecutionHandler 接口自定义处理策略。public interface RejectedExecutionHandler {   void rejectedExecution(Runnable r, ThreadPoolExecutor executor); } 复制代码
  keepAliveTime(线程存活时间):线程池的工作线程空闲后,保持存活的时间。
  TimeUnit(存活时间单位):可选单位DAYS(天)、HOURS(小时)、MINUTES(分钟)、MILLISECONDS(毫秒)、MICROSECONDS(微妙)、NANOSECONDS(纳秒)。
  ThreadFactory(线程工厂):可以通过线程工厂给创建出来的线程设置有意义的名字。
  创建线程池主要分为两大类,第一种是通过 Executors 工厂类创建线程池,第二种是自定义创建线程池。根据《阿里java开发手册》中的规范,线程池不允许使用 Executors 去创建,原因是规避资源耗尽的风险。使用 Executors 工厂类创建
  创建一个单线程化的线程池public static ExecutorService newSingleThreadExecutor() {   return new FinalizableDelegatedExecutorService     (new ThreadPoolExecutor(1, 1,                             0L, TimeUnit.MILLISECONDS,                             new LinkedBlockingQueue())); } 复制代码
  创建固定线程数的线程池public static ExecutorService newFixedThreadPool(int nThreads) {   return new ThreadPoolExecutor(nThreads, nThreads,                                 0L, TimeUnit.MILLISECONDS,                                 new LinkedBlockingQueue()); } 复制代码
  以上两种创建线程池方式使用链表阻塞队列来存放任务,实际场景中可能会堆积大量请求导致 OOM
  创建可缓存线程池public static ExecutorService newCachedThreadPool() {   return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                 60L, TimeUnit.SECONDS,                                 new SynchronousQueue()); } 复制代码
  允许创建的线程数量最大为 Integer.MAX_VALUE,当创建大量线程时会导致 CPU 处于重负载状态和 OOM 的发生自定义创建线程池public ThreadPoolExecutor(int corePoolSize,                           int maximumPoolSize,                           long keepAliveTime,                           TimeUnit unit,                           BlockingQueue workQueue) {   this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,     Executors.defaultThreadFactory(), defaultHandler); } 复制代码向线程池提交任务
  向线程池提交任务可以使用两个方法,分别为 execute() 和 submit()。
  execute() 方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。execute() 方法中传入的是 Runnable 类的实例。public static void main(String [] args){   ...   threadPool.execute(new Runnable{   public void run(){     //do something...   } });   ... } 复制代码
  submit() 方法用于提交需要返回值的任务。线程池会返回一个 Future 类型的对象,通过 future 对象可以判断任务是否执行成功,并且可以通过 future 的 get() 方法来获取返回值。get() 方法会阻塞当前线程直到任务完成,使用 get(long timeout, TimeUnit unit)方法会阻塞当前线程一段时间后立即返回,这时候可能任务没有执行完。public static void main(String [] args){   ...   Future future = threadPool.submit(handleTask);   try{   	Objects res = future.get();   }catch(InterruptedException e){   	//处理中断异常   }catch(ExecutionException e){   	//处理无法执行异常   }finally{   	threadPool.shutdown();   }   ... } 复制代码关闭线程池
  可以通过调用线程池的 shutdown() 或shutdownNow() 方法来关闭线程池。他们的原理是遍历线程池中的工作线程,然后逐个调用 interrupt() 方法来中断线程,所以无法响应中断任务可能永远无法终止。public void shutdown() {   final ReentrantLock mainLock = this.mainLock;   mainLock.lock();   try {     checkShutdownAccess();     advanceRunState(SHUTDOWN);     interruptIdleWorkers();     onShutdown(); // hook for ScheduledThreadPoolExecutor   } finally {     mainLock.unlock();   }   tryTerminate(); }  public List shutdownNow() {   List tasks;   final ReentrantLock mainLock = this.mainLock;   mainLock.lock();   try {     checkShutdownAccess();     advanceRunState(STOP);     interruptWorkers();     tasks = drainQueue();   } finally {     mainLock.unlock();   }   tryTerminate();   return tasks; } 复制代码
  shutdown() 和 shutdownNow() 方法的区别在于 shutdownNow 方法首先将线程池的状态设置为 STOP,然后尝试停止正在执行或暂停任务的线程,并返回等待执行任务的列表,而 shutdown 只是将线程池的状态设置成 SHUTDOWN 状态,然后中断所有没有正在执行任务的线程。//shutdownNow() private void interruptWorkers() {   final ReentrantLock mainLock = this.mainLock;   mainLock.lock();   try {     for (Worker w : workers)       w.interruptIfStarted();   } finally {     mainLock.unlock();   } } ... void interruptIfStarted() {   Thread t;   if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {     try {       t.interrupt();     } catch (SecurityException ignore) {     }   } } 复制代码//shutdown() private void interruptIdleWorkers() {   interruptIdleWorkers(false); } ...   private void interruptIdleWorkers(boolean onlyOne) {   final ReentrantLock mainLock = this.mainLock;   mainLock.lock();   try {     for (Worker w : workers) {       Thread t = w.thread;       if (!t.isInterrupted() && w.tryLock()) {         try {           t.interrupt();         } catch (SecurityException ignore) {         } finally {           w.unlock();         }       }       if (onlyOne)         break;     }   } finally {     mainLock.unlock();   } } 复制代码3、线程池参数设置推荐
  线程池使用面临的核心的问题在于:线程池的参数并不好配置。一方面线程池的运行机制不是很好理解,配置合理需要强依赖开发人员的个人经验和知识;另一方面,线程池执行的情况和任务类型相关性较大,IO 密集型和 CPU 密集型的任务运行起来的情况差异非常大,这导致业界并没有一些成熟的经验策略帮助开发人员参考。
  (1)以任务型为参考的简单评估:
  假设线程池大小的设置(N 为 CPU 的个数)
  如果纯计算的任务,多线程并不能带来性能提升,因为 CPU 处理能力是稀缺的资源,相反导致较多的线程切换的花销,此时建议线程数为 CPU 数量或+1;----为什么+1?因为可以防止 N 个线程中有一个线程意外中断或者退出,CPU 不会空闲等待。
  如果是 IO 密集型应用, 则线程池大小设置为 2N+1. 线程数 = CPU 核数   目标 CPU 利用率  (1 + 平均等待时间 / 平均工作时间)
  (2)以任务数为参考的理想状态评估:
  1)默认值corePoolSize=1 queueCapacity=Integer.MAX_VALUE maxPoolSize=Integer.MAX_VALUE keepAliveTime=60s allowCoreThreadTimeout=false rejectedExecutionHandler=AbortPolicy() 复制代码
  2)如何设置 * 需要根据相关值来决定 - tasks :每秒的任务数,假设为500~1000 - taskCost:每个任务花费时间,假设为0.1s - responsetime:系统允许容忍的最大响应时间,假设为1s计算获取corePoolSize = 每秒需要多少个线程处理?threadcount = tasks / ( 1 / taskCost ) =tasks*taskcout = (5001000)x0.1 = 50100 个线程。corePoolSize 设置应该大于 50根据 8020 原则,如果 80% 的每秒任务数小于800,那么 corePoolSize 设置为80 即可queueCapacity = ( coreSizePool / taskCost ) * responsetime计算可得 queueCapacity = 80/0.1*1 = 800。意思是队列里的线程可以等待 1s,超过了的需要新开线程来执行切记不能设置为 Integer.MAX_VALUE,这样队列会很大,线程数只会保持在 corePoolSize 大小,当任务陡增时,不能新开线程来执行,响应时间会随之陡增。maxPoolSize = (max(tasks) - queueCapacity) / ( 1 / taskCost)计算可得 maxPoolSize = (1000-800)/10 = 20 (+50)(最大任务数-队列容量)/ 每个线程每秒处理能力 = 最大线程数rejectedExecutionHandler:根据具体情况来决定,任务不重要可丢弃,任务重要则要利用一些缓冲机制来处理keepAliveTime 和 allowCoreThreadTimeout 采用默认通常能满足
  以上都为理想值,实际情况下要根据机器性能来决定。如果在未达到最大线程数的情况机器 cpu load 已经满了,则需要通过升级硬件和优化代码,降低 taskCost 来处理。
  (仅为简单的理想状态的评估,可作为线程池参数设置的一个参考)4、线程池使用场景推荐场景一
  与主业务无直接数据依赖的从业务可以使用异步线程池来处理,在项目初始化时创建线程池并交给将从业务中的任务提交给异步线程池执行能够缩短响应时间。/** *  创建线程池使用异步注解方式调用 */ @Bean public ThreadPoolTaskExecutor asyncExecutorPool() {   ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();   /**配置核心线程数*/   executor.setCorePoolSize(20);   /**配置最大线程数*/   executor.setMaxPoolSize(100);   /**配置队列大小*/   executor.setQueueCapacity(500);   /**等待任务在关机时完成--表明等待所有线程执行完*/   executor.setWaitForTasksToCompleteOnShutdown(true);   /** 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止*/   executor.setAwaitTerminationSeconds(60);   /**配置线程池中的线程的名称前缀*/   executor.setThreadNamePrefix("test-async-thread-");   /**rejection-policy:当pool已经达到max size的时候,如何处理新任务(CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行)*/   executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());   /**初始化执行器*/   executor.initialize();    return executor; }  //使用@Async异步注解 @Async("asyncExecutorPool") public void processTask1() {   //doSomething } 复制代码
  严禁在业务代码中起线程!!!/** *  创建线程池直接使用 */ public class ThreadPoolExecutorTest{      private ThreadPoolExecutor executor;      @PostConstruct   public void init() {     /** 线程池初始化 */     ThreadPoolExecutor threadPoolExecutor =        new ThreadPoolExecutor(30, 60, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(200));     threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());     ThreadFactory threadFactory = new CustomizableThreadFactory("test-creates-thread-");     threadPoolExecutor.setThreadFactory(threadFactory);     this.executor = threadPoolExecutor;   }   ...    public void processTask(){     Future<> future = executor.submit(     //doSomething...     );   }    } 复制代码场景二
  当任务需要按照指定顺序(FIFO, LIFO, 优先级)执行时,推荐创建使用单线程化的线程池。public class SingleExecutorTest{      private HashMap executorMap = new HashMap<>();   ...   public void init() {   /** 线程池初始化 */     for (int i = 0; i < 5; i++) {       /**任务队列容量:1000*/       ThreadPoolExecutor threadPoolExecutor =          new ThreadPoolExecutor(1, 1,0,                                 TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000));       /**拒绝策略:静默丢弃,不抛异常*/       threadPoolExecutor.setRejectedExecutionHandler(         new ThreadPoolExecutor.DiscardPolicy());       ThreadFactory threadFactory = new CustomizableThreadFactory("testSingle-"+ i +"-");       threadPoolExecutor.setThreadFactory(threadFactory);       executorMap.put(Long.valueOf(i),threadPoolExecutor);     } 	}   ...   /** 需要顺序执行的任务 */    public void processTask(){     ...     /** 获取单一线程池 */     ThreadPoolExecutor executor = executorMap.get(Long.valueOf(id % 5));     /** 向线程池中提交任务 */     excutor.submit(       //doSomething...     );   } } 复制代码总结
  本文章主要说明了线程池的执行原理和创建方式以及推荐线程池参数设置和一般使用场景。在开发中,开发人员需要根据业务来合理的创建和使用线程池达到降低资源消耗,提高响应速度的目的。
  原文链接:https://juejin.cn/post/7067324722811240479
立秋后,我们能吃什么?不能多吃什么?立秋夏尽秋来,风吹一片叶,万物已惊秋。秋天来了,在此时节我们不能多吃什么?能吃什么?一起来看看吧。一起来看看吧!一不宜多什么1不宜多吃西瓜,西瓜属于寒凉食物,若大量食用可能会加重体明日出伏,无论男女,常吃5种食物,补虚乏益气力,秋天要懂得吃人不管走到哪一步,总得找点乐子,想一点办法。是的,美食就是我找的乐子,想的办法!小谈食刻和你一起认真对待吃下的食物!导读农历的七月廿八会迎来末伏的最后一天,也称之为出伏。出伏以后,敢遮挡两亿豪宅视线!C罗下令买下隔壁高尔夫俱乐部然后拆了它退役后的C罗会在哪里定居和生活?这个问题似乎早已经没有了悬念,在葡萄牙里斯本以西30公里处的里维埃拉卡斯凯什富人聚集区,C罗正在打造一座总面积超过3000平方米的豪宅。根据英国媒体由于3500万英镑的要求,曼联结束了对马竞前锋的兴趣据竞技的报道,曼联已经结束了对马竞前锋阿尔瓦罗莫拉塔的兴趣,因为他们认为西班牙人太贵了。曼彻斯特联队今年夏天拼命在市场上寻找一名新的中锋。为此,他们已经和很多名字联系在一起,包括三宝贝咳嗽,请注意这些食物不许吃随着气温越来越凉,许多宝贝都被咳嗽找上了门,一时间稚嫩的咳嗽声经常回荡在耳畔。针对宝贝咳嗽的情况,父母们绝对是很揪心的,但同时也要注意宝贝的饮食,宝贝在咳嗽期间,饮食尽量要清淡一些胃不好的人,这7种食物尽量少碰,避免加重胃病不适在生活中,许多人由于饮食不当而引起胃病,特别是近年来,胃炎胃溃疡等发病率特别高。事实上,引致胃部问题的因素很多,例如幽门螺杆菌感染不健康的饮食滥用药物经常进食辛辣食物等。一如果胃不8月25日出伏,建议多吃2鱼,常饮3茶,顺利度秋夜久眠难得,秋声踏树梢。时间过得快真快啊,一眨眼末伏就要结束了,随着8月25日出伏的到来,煎熬的三伏天也算是画上了圆满的句号。出伏后,温度偏低,气候也逐渐凉爽起来,但大家也别高兴的新一期世界排名公布国足亚洲十名开外,巴西稳居世界第一北京时间8月25日,国际足联公布了最新一期世界排名。巴西以1837。56分位列世界第一,中国队位列世界78位,亚洲第11位。在最新的世界排名中,巴西比利时阿根廷法国英格兰西班牙意大羽毛球世锦赛国羽男单仅剩独苗赵俊鹏胜大马一哥带来惊喜北京时间8月25日傍晚,2022日本羽毛球世锦赛国羽两位男单选手冲击八强的比赛结束。国羽三号赵俊鹏表现不俗,爆出冷门,2比1将马来西亚一哥李梓嘉拉下了马,昂首晋级14决赛。但是被球奥运冠军变第61名,杨倩时隔1年大滑坡!杨皓然绝境爆发逆转夺冠2022年全国射击锦标赛和2022年开罗世锦赛选拔赛在江苏南京举行。奥运冠军杨倩在这两项比赛中都表现不佳,其中在全锦赛她仅仅排名第61名。另外一位奥运冠军杨皓然则在选拔赛夺得冠军。20!国羽再造惊喜男单淘汰世界冠军,女单爆出首个大冷门北京时间2022年8月24日,羽毛球世锦赛继续进行,男单赛场,国羽再次制造惊喜,赵俊鹏以2比0淘汰上届世锦赛亚军得主斯里坎特,强势晋级16强,下一轮挑战李梓嘉。女单赛场,国羽的陈雨大爆冷!混双世界第一02完败,世锦赛卫冕冠军出局,戴资颖20北京时间8月25日,羽毛球世锦赛正在进行。正在进行的是混双比赛,刚刚结束的比赛中,爆出大冷门,混双世界第一泰国组合沙西丽德差波总比分02完败出局,不敌德国选手拉姆斯福斯伊莎贝尔,无NBA一夜6大突发交易杰伦布朗逼宫交易勇士决定放弃维金斯一詹姆斯怒斥管理层没有早把欧文交易过来随着杜兰特留守布鲁克林的决定,勒布朗和欧文再次联手的希望已经破灭,今天湖人内部记者透露詹姆斯对于湖人管理层没有早些把欧文交易过来表示愤怒,他表心脑血管疾病的早期症状有哪些,如何预防?心脑血管疾病早期症状之一就是嗜睡,部分患者还会有胸闷和疼痛现象,还有就是会出现头痛和头晕症状。1嗜睡有些心脑血管疾病患者晚上已经睡了很长时间,但白天还是感觉头发沉的现象,特别想睡觉语言肢体暴力家庭对孩子伤害有多大?如何疗愈孩子内伤相信很多家庭对孩子语言暴力伤害,张某从小出生与一个语言暴力家庭,在8月25日一天,张某与哥哥姐姐父母一块玉米地,哥哥姐姐说到掰玉米了!我们刚开始掰玉米一会儿。父母说我们大家一起比赛精神倦怠,身体乏力?一剂两仪膏气血双补,赶走疲倦,活力四射总是感觉到精神倦怠,身上没力气,能躺着绝对不坐着,做什么事情都懒洋洋的。刘医生提醒你可能是气血两虚了,今天我就给大家介绍一剂气血双补的两仪膏帮你赶走疲惫,让你活力四射。为什么说精神俗语秋天3不吃,吃了火不止,指的是哪3物?弄清楚好过秋虽然现在的天气依旧很炎热,但不得不承认的是,自从立秋过去,秋天已经来临。老祖宗曾言适时养生,根据不同的时节,采取不同的养生方式,才能更加有利于健康。如果在秋天的时候,仍然遵循夏季的交易扩大化!名嘴力挺湖人5换2,同时拿下米切尔贝弗利辅佐詹皇北京时间8月25日,洛杉矶湖人今日成功完成了一笔疯狂大交易,他们成功用2换1的筹码,得到了34岁的硬汉3D球员贝弗利。但是湖人接下来的交易还并没有结束,NBA名嘴ColinCowh曝江宏杰将赴日接家人,福原爱却揭其真面目,网友夺子大战开始说起福原爱许多人都不陌生,身为日本乒乓球运动员却可以说一口流利的东北话,也因长相甜美可爱深受大家喜欢,被网友亲切的成为爱酱。爱酱也因事业获得了爱情,在3年前与同为乒乓球运动员的江宏豆角不要炒着吃了,教你懒人做法,开胃下饭又解馋,比肉都不换三餐美味,四季幸福,大家好!豆角是我们常吃的蔬菜之一,它具有健脾和胃,加强肠胃蠕动,预防便秘等作用。豆角的做法有很多种,一般都是炒着吃。今天,我要给大家分享一个好吃的做法,方法非常连续闷杀!2022第一大牛股两跌停,6000万散户资金被割韭菜文杨万里2022年第一大牛股连续遭到空头重锤。8月24日,盈方微开盘一字跌停,盘中超59万手砸盘,创下两跌停纪录。截至发文,该公司股价为10。73元,总市值为87。62亿元。龙虎榜冠心病患者注意,有些食物再美味,也要管好嘴巴冠心病的患者其实我们更讲究的是饮食的管理与控制。一冠心病合并动脉粥样硬化很多冠心病的病人因为血管有动脉粥样硬化。那么这时候血脂的管理其实就非常重要了,在吃的方面,我们要尽量地减少脂
爸爸带娃示范冰面危险,结果自己却翻船了,网友这是熊爸爸每个人从呱呱坠地开始,对周围事物都是懵懂无知的,不知道什么行为是安全的,什么行为是危险的,都是在父母的引导下慢慢有了认知的。在引导孩子方面,有的父母是说教方式,有的父母是理论结合实谷爱凌吃的是韭菜盒子还是韭菜馅饼?网友聊嗨了今天(14日)的北京冬奥会自由式滑雪女子坡面障碍技巧资格赛上,中国选手谷爱凌迎来张家口赛区的首秀。最终她以79。38的得分排在第三位晋级决赛。第二跳完成后,在场边等待成绩的她从口袋老干妈要没落?美国辣酱1年大赚370亿,30年却一直伪装成国货众所周知,创业不易,要想在创业成功之后守住原有的基业更是难上加难。对于老品牌辣酱老干妈而言,更是如此。老干妈属于国内传统的家族式企业,始终坚持不上市不贷款不融资原则,但自从陶碧华的奖牌不保最新表态,韩国选手违规面临重罚,又把脏水泼给俄罗斯队奖牌不保!韩国选手面临重罚最新表态,把脏水泼给俄罗斯选手北京时间2月14日,速度滑冰男子500米决赛,韩国运动员车旼奎获得银牌。而该选手因为在赛后颁奖典礼上,做出擦拭领奖台的争议动全球资本市场动荡失控美联储要加息,俄乌局势再升级,全球资本市场大动荡,原油黄金等商品大涨,避险资产表现好于风险性投资,市场进入混沌剧变时刻。A股虎年首周开市不利,在巨大分歧之中,将春节前的分化行为更大冬奥最新奖牌榜中国斩第5金攀升第7,有望刷新历史,美国稳第3北京时间2月14日,2022年北京冬奥会结束了第10个奖牌日的争夺,在本个比赛日一共产生了4枚金牌,中国选手徐梦桃在自由式滑雪女子空中技巧项目的决赛中夺得冠军,帮助中国代表队夺得本CBA三消息赵睿返回广东,山西补强32岁老将,辽宁功勋决定退役CBA联赛第三阶段的消息终于确定了,按照CBA官方发布的消息,CBA第三阶段会在3月1日正式开打,到3月22日正式结束,分为沈阳赛区和顺德赛区两个赛区举行,随后各球队第三阶段的赛程油价调整消息今天2月15号调整后,全国加油站9295号汽油售价今天是2022年2月15日,也是上元佳节。截至国内油价调整的第7个工作日,参考原油油种周期内滚动均价为91。88美元桶,原油综合变化率3。93,预计对应国内汽柴油上调幅度165元吨正义降临?俄罗斯花滑名将摆脱禁赛,金牌保住了,但处罚在所难免一波三折后,在约50名相关人士的听证会后,国际体育仲裁法庭(CAS)公布,关于俄罗斯奥运队花样滑冰运动员卡米拉瓦利耶娃临时禁赛的申诉,被驳回,意味着K宝将可以出席明天18点进行的单2药增加血流量营养修复神经促进传导,改善糖尿病四肢麻凉疼糖尿病周围神经病变,主要是由于患者身体长期处于高血糖状态,导致微血管受损,进而引发周围神经组织障碍的疾病。该病大多会出现神经脱髓鞘损害,肢端麻凉疼,发生感染足部溃疡等并发症的风险增乙肝患者如何保护肝脏?医生提醒日常注意避开这些毁肝细节肝脏是人体内非常重要的脏器,具有调节机体代谢,分泌和排泄胆汁解毒及维持人体凝血和抗凝平衡的功能,如果人体的肝脏出现问题,那么以上功能都可能受影响。乙肝患者由于感染乙型肝炎病毒(HB