1.以下方法存在的问题newThread(){@Overridepublicvoidrun(){//业务逻辑}}.start();1、首先,频繁的创建和销毁对象是一件非常耗性能的事情;2、如果用户数量比较多,会占用过多的资源,可能导致我们的服务因资源不足而宕机;3.综上所述,在实际开发中,这种Operation其实是一种不可取的方式。二、使用线程池有什么好处1、提高了线程池中线程的利用率,减少了对象的创建和销毁;2、线程池可以控制线程数量,有效提高服务器资源的利用率,避免因资源不足而宕机3、线程池的四种使用方式1、newCachedThreadPool创建线程池。如果线程池中的线程数过多,可以有效回收冗余线程。如果线程数量不足,它可以创建新线程。溃败。publicstaticvoidmethod()throwsException{ExecutorServiceexecutor=Executors.newCachedThreadPool();for(inti=0;i<5;i++){finalintindex=i;Thread.sleep(1000);executor.execute(newRunnable(){@Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName()+""+index);}});}}通过分析执行结果可以看出,从头到尾都是一个线程执行的结束,实现了线程的复用,不会产生冗余线程。如果当我们的业务需要一定的时间来处理时,会发生什么。让我们模拟一下。可以清楚的看到现在需要几个线程交替执行。缺点:虽然这种方式可以根据业务场景自动扩展线程数来处理我们的业务,但是我们无法控制需要多少线程同时处理不足;优点:如果第二个任务启动,第一个任务执行完毕后,第二个任务会复用第一个任务创建的线程,不会重新创建新的线程,提高了线程复用率;2.newFixedThreadPool可以通过这种方式指定线程池中的线程数。例如,如果一间浴室最多只能容纳20人同时洗澡,那么后来来的人只能在外面排队等候。如果硬闯进去,那么只会出现一种情况,摩擦摩擦……先测试最大容量是一个线程,然后就是我们预测的结果。publicstaticvoidmethod_01()throwsInterruptedException{ExecutorServiceexecutor=Executors.newFixedThreadPool(1);for(inti=0;i<10;i++){Thread.sleep(1000);finalintindex=i;executor.execute(()->{try{线程.sleep(2*1000);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println(Thread.currentThread().getName()+""+index);});}执行者。shutdown();}执行结果,我们改成3线程再看结果。优点:两个结果说明newFixedThreadPool的线程数是可以控制的,所以我们可以通过控制最大线程数来最大化我们的服务器。使用率,同事们可以保证突然增加的流量不会占用太多服务器的资源。3.newScheduledThreadPool这个线程池支持定时和周期性的任务执行。我们可以延迟任务的执行时间,或者设置一个周期性的时间让任务重复执行。线程池中有以下两种延迟方法。scheduleAtFixedRate测试一publicstaticvoidmethod_02(){ScheduledExecutorServiceexecutor=Executors.newScheduledThreadPool(5);executor.scheduleAtFixedRate(newRunnable(){@Overridepublicvoidrun(){longstart=newDate().getTime();System.out.println("scheduleAtFixedRate开始时间:"+DateFormat.getTimeInstance().format(newDate()));try{Thread.sleep(5000);}catch(InterruptedExceptione){e.printStackTrace();}longend=newDate().getTime();System.out.println("scheduleAtFixedRate执行时间="+(end-start)/1000+"m");System.out.println("scheduleAtFixedRate执行完成时间:"+DateFormat.getTimeInstance().format(newDate()));System.out.println("=========================================");}},1,5,TimeUnit.SECONDS);}执行结果测试2总结:以上两种方法的区别在于任务的执行时间。如果间隔时间大于任务的执行时间,则任务不会受到执行时间的影响。如果间隔时间小于任务的执行时间,任务执行结束后会立即执行,间隔时间会被打乱。scheduleWithFixedDelaytestpublicstaticvoidmethod_03(){ScheduledExecutorServiceexecutor=Executors.newScheduledThreadPool(2);executor.scheduleWithFixedDelay(newRunnable(){@Overridepublicvoidrun(){longstart=newDate().getTime();System.out.println("scheduleDelayWithFixed开始执行时间:"+DateFormat.getTimeInstance().format(newDate()));try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}longend=newDate().getTime();System.out.println("scheduleWithFixedDelay执行时间="+(end-start)/1000+"m");System.out.println("scheduleWithFixedDelay执行完成时间:"+DateFormat.getTimeInstance().format(newDate()));System.out.println("=========================================");}},1,2,TimeUnit.SECONDS);}执行结果测试2publicstaticvoidmethod_03(){ScheduledExecutorServiceexecutor=Executors.newScheduledThreadPool(2);executor.scheduleWithFixedDelay(newRunnable(){@Overridepublicvoidrun(){longstart=newDate().getTime();System.out.println("scheduleWithFixedDelay开始执行时间:"+DateFormat.getTimeInstance().format(newDate()));try{Thread.sleep(5000);}catch(InterruptedExceptione){e.printStackTrace();}longend=newDate().getTime();System.out.println("scheduleWithFixedDelay执行时间="+(end-start)/1000+"m");System.out.println("scheduleWithFixedDelay执行完成时间:"+DateFormat.getTimeInstance().format(newDate()));System.out.println("========================================");}},1,2,TimeUnit.SECONDS);}执行结果总结:同理scheduleWithFixedDelay测试方法,可以测出scheduleWithFixedDelay的间隔时间不会受到任务执行时间长度4.newSingleThreadExecutor这是一个单线程池,从头到尾由一个线程执行。publicstaticvoidmethod_04(){ExecutorServiceexecutor=Executors.newSingleThreadExecutor();for(inti=0;i<5;i++){finalintindex=i;executor.execute(()->{try{Thread.sleep(2*1000);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println(Thread.currentThread().getName()+""+index);});}executor.shutdown();}执行结果4.线程池的作用线程池的作用主要是提高系统的性能和利用率。文章开头提到,如果我们用最简单的方式创建线程,如果用户数量比较多,创建和销毁线程的动作会很多,会导致服务器在创建时消耗更多的性能并破坏线程。比处理实际业务更多的时间和性能。线程池就是为了解决这类问题而产生的。类似的设计还有很多,比如数据库连接池。但是由于经常连接数据库,创建连接是一件很耗性能的事情,所有的数据库连接池都出现了。
