title: Do my code may casuse memory leak or too many udp link?
body: <p>I want to use snmp method to query some data by mutithread in sometime,if over time,then the task will be cancel,I write the code like this, if there is something wrong with my code(It means that the thread may only do step 1and step 2,but do not do the step 4:close snmp connetction),how to fix ?Can I have the method that is the task is cancel,I can still close the snmp clent at step 4?</p>
  <pre><code>public static void main(String[] args) throws InterruptedException {
      var pool = new ThreadPoolExecutor(
              100, 100, 0L, TimeUnit.NANOSECONDS, new LinkedBlockingQueue&lt;&gt;(100)); 
          System.out.println(&quot;Executing first batch of tasks...&quot;);
          submitTasks(pool);
          System.out.println(&quot;Finish first  batch of tasks...&quot;); 
          //call submitTasks(pool) many times
          ...
       }
    private static void submitTasks(ExecutorService executor) throws InterruptedException {
      var tasks = new ArrayList&lt;Callable&lt;String&gt;&gt;(100);
      for (int i = 0; i &lt; 100; i++) {
          tasks.add(() -&gt; {
              try {
                  //1.create snmp client
                   //2.query data with udp link
                   //3.return result 
                       return result;
              }catch (Exception ex){
                  log.error(String.valueOf(ex));
              }  
          } finally {
           //4.close snmp
          if (snmp != null) { 
            snmp.close(); 
          }
          }
              
          });
      }
      List&lt;Future&lt;String&gt;&gt; futureList=executor.invokeAll(tasks,1,TimeUnit.SECONDS);
         List&lt;String&gt; list=new ArrayList&lt;&gt;();
      for (int i = 0; i &lt; futureList.size(); i++) {
          Future&lt;String&gt; future = futureList.get(i);
          try {
              list.add(future.get());
          } catch (CancellationException e) {
              log.info(&quot;timeOut Task：{}&quot;, i);
          } catch (Exception e) {
              log.error(e.getMessage(), e);
          }
      } 
  }
  </code></pre>
  <p>I have change the code from Alexander Pavlov's example,it seems that if the task is cancel,the finally code will never run.</p>
  <pre><code>public static void main(String[] args) throws InterruptedException {
      var pool = new ThreadPoolExecutor(
              3, 3, 0L, TimeUnit.NANOSECONDS, new LinkedBlockingQueue&lt;&gt;(1));
      try {
          System.out.println(&quot;Executing first batch of tasks...&quot;);
          submitTasks(pool);
          System.out.println(&quot;Executing second batch of tasks...&quot;);
      } finally {
          pool.shutdown();
      }
  }
  
  private static void submitTasks(ExecutorService executor) throws InterruptedException {
      var tasks = new ArrayList&lt;Callable&lt;String&gt;&gt;(3);
      final var latch = new CountDownLatch(3);
      log.info(String.valueOf(latch.getCount()));
      for (int i = 0; i &lt; 3; i++) {
          tasks.add(() -&gt; {
              try {
                  String s=&quot;1&quot;;
                  log.info(&quot;this.name:&quot;+Thread.currentThread().getName());
                  for(int a=0;a&lt;1000000L;a++) {
                     s=a+&quot;&quot;;
                  }
                      return s;
              }catch (Exception ex){
                  log.error(String.valueOf(ex));
              }finally {
                  latch.countDown();
              }
              return  null;
          });
      }
      List&lt;Future&lt;String&gt;&gt; futureList=executor.invokeAll(tasks,1,TimeUnit.NANOSECONDS);
         List&lt;String&gt; list=new ArrayList&lt;&gt;();
  
      //latch.await();//
      for (int i = 0; i &lt; futureList.size(); i++) {
          Future&lt;String&gt; future = futureList.get(i);
          try {
              list.add(future.get());
          } catch (CancellationException e) {
              log.info(&quot;timeOut Task：{}&quot;, i);
          } catch (Exception e) {
              log.error(e.getMessage(), e);
          }
      }
      log.info(String.valueOf(latch.getCount()));
      log.info(&quot;start to await:&quot;);
      try {
          latch.await(); // WAIT UNTIL ALL TASKS ARE REALLY DONE
      } catch (InterruptedException ex) {
          log.error(String.valueOf(ex));
      }
      //never log end to await
      log.info(&quot;end to await:&quot;);
      log.info(String.valueOf(latch.getCount()));
  }
  </code></pre>