mercredi 5 août 2015

Task Scheduling using threads in java


I am currently working on a DB integrated daily file transfer scheduling form application for operational business use. In order to be able to control and have access to specific schedules, I have decided to create a thread for each schedule so that a specific schedule could be stopped, or restarted on demand. To achieve this, I have written a separate class which includes a custom thread class and its constructor, a main class to create and run an instance of thread and another class that includes the runnable method of daily scheduling. In order to be able to access specific threads, I have tried to implement a ConcurrentHashMap to synchronise the hashcodes and the names of the threads created, along with a ThreadGroup. When I create a thread, I am able to pass the name and the hashcode of the thread to the ConcurrentHashMap, along with the ThreadGroup. However, when I create the second or the third thread, I have discovered that the specified names and the hashcodes of the threads that have been specified are changing. The class that I have explained above could be seen below.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.logging.Level;
import java.util.logging.Logger;
import static sun.misc.ThreadGroupUtils.getRootThreadGroup;

public class ThreadRun
{
   static String name, s, d;
   static int h = 0;
   static int m = 0;
   ThreadGroup tg = Thread.currentThread().getThreadGroup();
   Thread[] threads;

   public void start (String n, String src, String dest, int hour, int min) 
   {
            name = n;
            s = src;
            d = dest;
            h = hour;
            m = min;
            MyThread mt = new MyThread(tg,name,s,d,h,m);
            mt.setName(name);
            mt.start ();
            System.out.println("Thread: " + mt.getName() + "is started!");
            getThread();

      }

   Thread[] getAllThreads(ThreadGroup tg) {
   // tg = Thread.currentThread().getThreadGroup();
    final ThreadMXBean thbean = ManagementFactory.getThreadMXBean( );
    int nAlloc = thbean.getThreadCount( ) + 1;
    int n = 0;
    Thread[] threads;
    do {
        nAlloc *= 2;
        threads = new Thread[ nAlloc ];
        n = tg.enumerate( threads, true );
    } while ( n == nAlloc );
    return java.util.Arrays.copyOf( threads, n );
} //getting all the active threads to an array

   void getThread() //getting a specific thread
   {
    final Thread[] threads = getAllThreads(tg);
    for ( Thread thread : threads )
      System.out.println("ThreadName = " + thread.getName());
}

  static class MyThread extends Thread{

      MyThread(ThreadGroup tg, String name, String src, String dest, int hour, int min)
      {
            super(tg,name);
      }

      @Override
         public void run () // run thread
        {
            ScheduleControl sc = new ScheduleControl();
            sc.scheduleDaily();
         //System.out.println ("My name is: " + getName ());
        }

 //SCHEDULE ZAMAZEENGO

class ScheduleControl {
   ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(20);       

   public void scheduleDaily() {
     final Runnable task = new Runnable() {


         @Override
       public void run() 
       { 
           try {
               t(s,d,h,m);
           } catch (IOException ex) {
               Logger.getLogger(MyThread.class.getName()).log(Level.SEVERE, null, ex);
           }
       }
     };

        LocalDateTime localNow = LocalDateTime.now();
        ZoneId currentZone = ZoneId.of("CET");
        ZonedDateTime zonedNow = ZonedDateTime.of(localNow, currentZone);

        ZonedDateTime zonedNext5 = zonedNow.withHour(h).withMinute(m).withSecond(0);

        if(zonedNow.compareTo(zonedNext5) > 0)
        zonedNext5 = zonedNext5.plusDays(1);


        Duration duration = Duration.between(zonedNow, zonedNext5);
        long initalDelay = duration.getSeconds();

        System.out.println("Schedule is started at\n" + LocalDateTime.now().getHour()+ ":" + LocalDateTime.now().getMinute());
        //System.out.println("Initial delay: " + initalDelay/60/60);
        final ScheduledFuture<?> scheduleHandle =
        scheduler.scheduleAtFixedRate(task, initalDelay , 24*60*60, SECONDS);

        scheduler.schedule(new Runnable() {
       @Override
       public void run() 
       {
           scheduleHandle.cancel(true);
       }
     }, 60*60, SECONDS);
   }


public Runnable t (String source, String destin, int h, int m) throws IOException
       {
           File srcF = new File(""+source);
           File destF = new File(""+destin);
           copyFolder(srcF,destF);
           System.out.println("Schedule finished at: " +LocalDateTime.now().getHour() + ":" +LocalDateTime.now().getMinute() + ":" +LocalDateTime.now().getSecond());
           return null;
       }
        public void copyFolder(File src, File dest)
        throws IOException{

        if(src.isDirectory()){

            //if directory not exists, create it
            if(!dest.exists()){
               dest.mkdir();
               System.out.println("Directory copied from " 
                              + src + "  to " + dest);
            }

            //list all the directory contents
            String files[] = src.list();

            for (String file : files) {
               //construct the src and dest file structure
               File srcFile = new File(src, file);
               File destFile = new File(dest, file);
               //recursive copy
               copyFolder(srcFile,destFile);
            }
        }
        else
        {
            OutputStream out;
                try ( //if file, then copy it
                //Use bytes stream to support all file types

                        InputStream in = new FileInputStream(src)) {
                    out = new FileOutputStream(dest);
                    byte[] buffer = new byte[1024];
                    int length;
                    //copy the file content in bytes
                    while ((length = in.read(buffer)) > 0){
                        out.write(buffer, 0, length);
                }
                }
                out.close();
                System.out.println("File copied from " + src + " to " + dest);
            }
        }
    }
  }
}

I have activated two different schedules for each to be run by a thread. The output of the active threads could be seen

Thread: Test 1 is started!
ThreadName = AWT-EventQueue-0
ThreadName = DestroyJavaVM
ThreadName = Test 1
Schedule is started at 12:
Thread: Test 2 is started!
ThreadName = AWT-EventQueue-0
ThreadName = DestroyJavaVM
ThreadName = pool-1-thread-1
ThreadName = pool-1-thread-2
ThreadName = Test 2
Schedule is started at
12:25

As it could be seen in the output above, there are three (3) threads instead of two and the specified name has been changed. I would like to be able to have static names and hashcodes for specific operation so that I can stop, pause, resume or delete by accessing each specifically. Thus I wonder what might be causing the problem, or what I have implemented in a wrong way.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire