精华内容
下载资源
问答
  • 解决Java线程池任务执行完毕后线程回收问题

    解决Java线程池任务执行完毕后线程回收问题

    参考文章:

    (1)解决Java线程池任务执行完毕后线程回收问题

    (2)https://www.cnblogs.com/pengineer/p/5011965.html


    备忘一下。


    展开全文
  • Java线程池任务执行完毕后回收线程

    万次阅读 2019-02-27 15:54:27
    Java线程池任务执行完毕后回收线程 线程池中的所有任务执行完毕后,线程并没有停止,导致JVM出现OOM问题。后来查找了下面链接的资料,解决问题。 ref: http://www.cnblogs.com/pengineer/p/5011965.html 问题及现象:...

    Java线程池任务执行完毕后回收线程

    线程池中的所有任务执行完毕后,线程并没有停止,导致JVM出现OOM问题。后来查找了下面链接的资料,解决问题。
    ref: http://www.cnblogs.com/pengineer/p/5011965.html

    问题及现象:

       public static void main(String[] args) {
       	BlockingQueue queue = new LinkedBlockingQueue();
       	ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 10, TimeUnit.SECONDS, queue);
       	for (int i = 0; i < 20; i++) {
       		executor.execute(new Runnable() {
       			@Override
       			public void run() {
       				try {
       					System.out.println(this.hashCode() / 1000);
       					for (int j = 0; j < 10; j++) {
       						System.out.println(this.hashCode() + ":" + j);
       						Thread.sleep(this.hashCode() % 2);
       					}
       				} catch (InterruptedException e) {
       					e.printStackTrace();
       				}
       				System.out.println(String.format("thread %d finished", this.hashCode()));
       			}
       		});
       	}
       }
    

    在这里插入图片描述
    任务已经执行完毕了,但是线程池中的线程并没有被回收,程序任然处于运行状态。但是在ThreadPoolExecutor的参数里面设置了超时时间的,好像没起作用,原因如下:
    工作线程回收需要满足三个条件:

    1. 参数allowCoreThreadTimeOut为true
    2. 该线程在keepAliveTime时间内获取不到任务,即空闲这么长时间
    3. 当前线程池大小 > 核心线程池大小corePoolSize。

    解决一:allowCoreThreadTimeOut设置为true

          public static void method1() {
              BlockingQueue queue = new LinkedBlockingQueue();
              ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, queue);  
              executor.allowCoreThreadTimeOut(true);
              for ( int i = 0; i < 20; i++) {
                  executor.execute( new Runnable() {
                      public void run() {
                          try {
                               System. out.println( this.hashCode()/1000);
                                  for ( int j = 0; j < 10; j++) {
                                    System. out.println( this.hashCode() + ":" + j);
                                    Thread. sleep(this.hashCode()%2);
                               } 
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          System. out.println(String. format("thread %d finished", this.hashCode()));
                      }
                  });
              }
          }
    

    需要注意的是,allowCoreThreadTimeOut 的设置需要在任务执行之前,一般在new一个线程池后设置;在allowCoreThreadTimeOut设置为true时,ThreadPoolExecutor的keepAliveTime参数必须大于0。

    解决二:调用shutdown方法

         public static void method1() {
              BlockingQueue queue = new LinkedBlockingQueue();
              ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, queue);
              for ( int i = 0; i < 20; i++) {
                  executor.execute( new Runnable() {
                      public void run() {
                          try {
                              System. out.println( this.hashCode()/1000);
                                for ( int j = 0; j < 10; j++) {
                                   System. out.println( this.hashCode() + ":" + j);
                                   Thread. sleep(this.hashCode()%2);
                              } 
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          System. out.println(String. format("thread %d finished", this.hashCode()));
                      }
                  });
              }         
              executor.shutdown();
          }
    

    在任务执行完后,调用shutdown方法,将线程池中的空闲线程回收。该方法会使得keepAliveTime参数失效。

    展开全文
  • 主要介绍了Java判断线程池线程是否执行完毕,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • java 等待线程/线程池执行完毕

    千次阅读 2017-08-07 15:43:54
    1.单线程开始并执行完毕 当线程开始后,需要用到join的方法 不废话直接贴代码 public static void main(String args[]) { long begin = System.currentTimeMillis(); System.out.println(begin); Thread thread...

    1.单线程开始并执行完毕
    当线程开始后,需要用到join的方法
    不废话直接贴代码

       public static void main(String args[]) {
            long begin = System.currentTimeMillis();
            System.out.println(begin);
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("111");
                }
            });
            try {
                thread.start();
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long end = System.currentTimeMillis();
            System.out.println(end-begin);
            System.out.println("执行完毕");
        }

    运行结果:

    1502091332017
    111
    1002
    执行完毕

    现在我们来看一下join这个方法

        /**
         * Waits for this thread to die.
         *
         * <p> An invocation of this method behaves in exactly the same
         * way as the invocation
         *
         * <blockquote>
         * {@linkplain #join(long) join}{@code (0)}
         * </blockquote>
         *
         * @throws  InterruptedException
         *          if any thread has interrupted the current thread. The
         *          <i>interrupted status</i> of the current thread is
         *          cleared when this exception is thrown.
         */
        public final void join() throws InterruptedException {
            join(0);
        }
        翻译为中文大意就是,等待线程执行完毕!

    2.等待线程池执行完毕
    等待线程池执行完毕我们需要用到
    CountDownLatch这个类
    且看代码:

        public static void main(String args[]) throws InterruptedException {
            final CountDownLatch count = new CountDownLatch(3);
            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
            try {
                long begin = System.currentTimeMillis();
                System.out.println(begin);
                fixedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000L);
                            count.countDown();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("111");
                    }
                });
                fixedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000L);
                            count.countDown();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("222");
                    }
                });
                fixedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(3000L);
                            count.countDown();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("333");
                    }
                });
    
                count.await();
                long end = System.currentTimeMillis();
                System.out.println(end-begin);
                System.out.println("执行完毕");
            } finally {
                fixedThreadPool.shutdown();
            }
        }

    最后一定要记得线程池关闭, 要不会出大问题的
    运行结果:

    1502091739441
    111
    222
    333
    3002
    执行完毕
    展开全文
  • Java 判断线程池 执行完毕

    千次阅读 2014-04-14 20:10:36
    工作中,遇到很多情况需要使用线程,或者线程池。但往往我们需要dengda

    工作中,遇到很多情况需要使用线程,或者线程池。但往往我们需要等待线程池执行结束后,使用执行结束后的数据做下一步操作。

    很多人提供的轮询,这样无形增加服务器的压力。

    现在使用JDK 1.5 提供线程池ExecutorService类配合Future接口来实现。 Future接口是Java标准API的一部分,在java.util.concurrent包中。Future接口是Java线程Future模式的实现,可以来进行异步计算

    Future模式可以这样来描述:我有一个任务,提交给了Future,Future替我完成这个任务。期间我自己可以去做任何想做的事情。一段时间之后,我就便可以从Future那儿取出结果。就相当于下了一张订货单,一段时间后可以拿着提订单来提货,这期间可以干别的任何事情。其中Future 接口就是订货单,真正处理订单的是Executor类,它根据Future接口的要求来生产产品。

    Future接口提供方法来检测任务是否被执行完,等待任务执行完获得结果,也可以设置任务执行的超时时间。这个设置超时的方法就是实现Java程序执行超时的关键。

    Future接口是一个泛型接口,严格的格式应该是Future<V>,其中V代表了Future执行的任务返回值的类型。 Future接口的方法介绍如下:

    • boolean cancel (boolean mayInterruptIfRunning) 取消任务的执行。参数指定是否立即中断任务执行,或者等等任务结束
    • boolean isCancelled () 任务是否已经取消,任务正常完成前将其取消,则返回 true
    • boolean isDone () 任务是否已经完成。需要注意的是如果任务正常终止、异常或取消,都将返回true
    • get () throws InterruptedException, ExecutionException  等待任务执行结束,然后获得V类型的结果。InterruptedException 线程被中断异常, ExecutionException任务执行异常,如果任务被取消,还会抛出CancellationException
    • get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException 同上面的get功能一样,多了设置超时时间。参数timeout指定超时时间,uint指定时间的单位,在枚举类TimeUnit中有相关的定义。如果计算超时,将抛出TimeoutException
    • void shutdown(); //停止线程
    • <T> Future<T> submit(Callable<T> task);

    Future的实现类有java.util.concurrent.FutureTask<V>即 javax.swing.SwingWorker<T,V>。通常使用FutureTask来处理我们的任务。FutureTask类同时又实现了Runnable接口,所以可以直接提交给Executor执行。

    package Thread;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class TestThread {
        public static void main(String[] args) {
            TestThread t =new TestThread();
            t.Test();
        }
        
        public void Test(){
            ExecutorService executorService = Executors.newFixedThreadPool(10);//线程池的大小
            List<Future<List<Integer>>> results = new ArrayList<Future<List<Integer>>>();//具体创建的线程对象
            for (int i =0; i< 4; i++) {
                ThreadObject v = new ThreadObject(i);
                Future<List<Integer>> result = executorService.submit(v);//执行线程
                results.add(result);//将此线程添加到线程list中
            }
            for(Future<List<Integer>> result : results){
                List<Integer> list = new ArrayList<Integer>();
                try {
                    list = result.get();//通过GET 获取线程的执行结果,如果没有执行结束,则此get方法会处于等待状态,知道线程执行结束
                } catch (Exception e) {
                }
                System.out.println(list.toString());
                System.out.println("END");
            }
            executorService.shutdown();//这里,则线程池中的线程都已经执行完毕了。所以关闭线程池
        }
    }
    

    package Thread;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    
    public class ThreadObject implements Callable<List<Integer>>{
        private int i;
        
        public ThreadObject(int i) {
            this.i = i;
            System.out.println("This is " + i);
        }
    
        @Override
        public List<Integer> call() throws Exception {
            List<Integer> list = new ArrayList<Integer>();
            for (int i =0; i< 10; i++) {
                list.add(i);
                System.out.println(this.i + " Thread: " + i);
                //Thread.sleep(100);
            }
            
            return list;
        }
    
    }
    

    展开全文
  • 线程池配置 ... * 执行io操作的线程池 */ @Bean public ThreadPoolExecutor ioPoolExecutor() { AtomicInteger incr = new AtomicInteger(0); ThreadFactory threadFactory = runnable -> {
  • 主要介绍了Java 判断线程池所有任务是否执行完毕的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 有个需求 1.单个任务放到线程池里去运行 2.任务运行完毕之后把自己重新塞回到线程池 3.外部信号决定单个任务是否停止将自己塞回线程池 应该是用定长线程池
  • Java 监控线程池所有任务是否执行完毕 场景引入 在最近的工作中遇到一个需要批量生产百万数据并写入数据库的需求,先通过单线程的方式去实现,但是感觉效率一般,然后通过多线程的方式去改进,但是遇到下面的问题:...
  • 但是,我们往往有这样的需要:要求在线程池中的任务完成后才能执行后续的任务,或者需要任务完成后释放资源或向数据库写入状态。这些需要我们判断线程池的任务是否已经完成。 判断线程池中的任务是否全部...
  • 其实这个问题的答案很容易知道,反向想一想,如果JVM关闭的时候如果真的需要等待每一个正在执行任务的线程执行完毕才完全关闭,那么如果有的任务执行非常耗时(或者直接就是死循环),那岂不是JVM永远不能退出了。...
  • c# ThreadPool 判断子线程全部执行完毕的四种方法1、先来看看这个多线程编程多线程用于数据采集时,速度明显很快,下面是基本方法,把那个auto写成采集数据方法即可。using System;using System.Collections.Generic...
  • 如何判断线程池中任务执行完毕 这里用到的是给用户提供反馈,判断多个异步操作执行完毕的结果。 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行。例如,应用程序的主线...
  • 调用ExecutorService.shutdown方法,线程池不再接收任何新的任务,但此时线程池并不会立刻退出,直到添加到线程池中的任务已经执行处理完成,才会退出,我们如何判断线程池中所有的子线程已经执行完毕,然后继续...
  • 判断线程池所有任务是否执行完毕

    千次阅读 2017-02-28 14:19:30
    创建一个固定大小的线程池。 shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭。 awaitTermination():用于等待子线程结束,再继续执行下面的代码。该例中我设置一直等着子线程结束。 public ...
  • Java如何判断线程池所有任务是否执行完毕 2014-10-18 23:10 16842人阅读 评论(0) 收藏 举报 [java] view plaincopy package csdn;   import java.util.concurrent.ExecutorService; import ...
  • 摘要: 当任务量较大时,我们需要开启线程执行任务,但是在... 判断线程是否全部执行完毕(CountDownLatch) CountDownLatch示例 1.线程池 开启线程的方法有很多: 1.spring管理的ThreadPoolTaskExecutor线程池 2...
  • 1.判断线程池中所有线程是否执行完毕根据线程池中的总线程数目等于完成的线程数目package com.luna.thread;import java.util.Random;import java.util.concurrent.LinkedBlockingQueue;import java.util.con...
  • 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。如果已经关闭,则调用没有其他作用。   抛出: SecurityException - 如果安全管理器存在并且关闭,此 ExecutorService 可能操作某些不允许调用者修改的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 70,803
精华内容 28,321
关键字:

线程池都执行完毕