docs: public synchronized void stop() {
          Thread tmp=runner;
          runner=null;
          if(tmp != null) {
              tmp.interrupt();
              try {tmp.join(500);} catch(InterruptedException e) {}
          }
  
          // we may need to do multiple iterations as the iterator works on a copy and tasks might have been added just
          // after the iterator() call returned
          while(!queue.isEmpty())
              for(Task entry: queue) {
                  entry.cancel(true);
                  queue.remove(entry);
              }
          queue.clear();
  
          if(pool instanceof ThreadPoolExecutor && shut_down_pool) {
              ThreadPoolExecutor p=(ThreadPoolExecutor)pool;
              List<Runnable> remaining_tasks=p.shutdownNow();
              remaining_tasks.stream().filter(task -> task instanceof Future).forEach(task -> ((Future)task).cancel(true));
              p.getQueue().clear();
              try {
                  p.awaitTermination(Global.THREADPOOL_SHUTDOWN_WAIT_TIME, TimeUnit.MILLISECONDS);
              }
              catch(InterruptedException e) {
              }
          }
  
          // clears the threads list (https://issues.jboss.org/browse/JGRP-1971)
          if(timer_thread_factory instanceof LazyThreadFactory)
              ((LazyThreadFactory)timer_thread_factory).destroy();
      }