使用java中的线程进行任务调度(已编辑)

时间:2015-08-05 09:45:28

标签: java multithreading thread-safety java-threads threadgroup

我目前正在开发一个数据库集成日常文件传输调度表单应用程序,用于运营业务。为了能够控制并访问特定的时间表,我决定为每个时间表创建一个线程,以便可以按需停止或重新启动特定的时间表。为了实现这一点,我编写了一个单独的类,其中包括一个自定义线程类及其构造函数,一个用于创建和运行线程实例的主类,以及另一个包含每日调度的runnable方法的类。为了能够访问特定的线程,我尝试实现ConcurrentHashMap来同步哈希码和创建的线程的名称以及ThreadGroup。当我创建一个线程时,我能够将线程的名称和哈希码与ThreadGroup一起传递给ConcurrentHashMap。但是,当我创建第二个或第三个线程时,我发现指定的名称和已指定的线程的哈希码正在发生变化。我在上面解释过的课程如下所示。

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.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
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;

public class ThreadRun
{
   static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(20);  
   static String name, s, d;
   static int h = 0;
   static int m = 0;
   static ThreadGroup tg = new ThreadGroup("ThreadGroup");
   static Map<String,Object> threadMap = 
           Collections.synchronizedMap(new HashMap<String,Object>(30));

   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);

            threadMap.put(name, mt.hashCode());
            mt.start();
            System.out.println("Thread: " + mt.getName() + " is started!");
            System.out.println("getThread");
            getThread(tg);
            System.out.println("getAllThreadMap");
            getAllThreadMap();

      }


   void getAllThreadMap()
   {
       Iterator it = threadMap.entrySet().iterator();
       while(it.hasNext())
       {
           Map.Entry pair = (Map.Entry)it.next();
           System.out.println(pair.getKey() + " = " + pair.getValue());
       }
   }

   Thread[] getAllThreads(ThreadGroup tg) {
    tg = Thread.currentThread().getThreadGroup();
    final ThreadMXBean thbean = ManagementFactory.getThreadMXBean( );
  //  System.out.println("Group active count: "+ tg.activeCount());
    int nAlloc = thbean.getThreadCount( ) + 2;
    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(ThreadGroup g) //getting a specific thread
   {
    final Thread[] threads = getAllThreads(g);
    for ( Thread thread : threads )
    {
        System.out.println("ThreadName = " + thread.getName() + " ThreadHash = " +thread.hashCode());
    }
}

  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();
        }


class ScheduleControl {


   public void scheduleDaily() {
     final Runnable task = new Runnable() {
         @Override
       public void run() 
       { 

             try {
                 t(s,d,h,m);
             } catch (IOException ex) {
                 Logger.getLogger(ThreadRun.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 

                    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);
            }
        }
    }
  }
}

我已经为每个线程运行了两个不同的计划。可以看到活动线程的输出

Thread: Test 1 is started! 
getThread
ThreadName = AWT-EventQueue-0 ThreadHash = 18329106
ThreadName = DestroyJavaVM ThreadHash = 21388846
ThreadName = Test 1 ThreadHash = 17676897
getAllThreadMap
Test 1 = 17676897
Thread: Test 2 is started!
getThread
ThreadName = AWT-EventQueue-0 ThreadHash = 18329106
ThreadName = DestroyJavaVM ThreadHash = 21388846
ThreadName = pool-1-thread-1 ThreadHash = 6119842 
ThreadName = Test 2 ThreadHash = 2586910
getAllThreadMap
Test 2 = 2586910
Test 1 = 17676897

正如在上面的输出中可以看到的,名为Test 2的Thread的名称和hashCode与已放入threadMap(hashMap)的值不对应。我希望能够为特定操作设置静态名称和哈希码,以便通过访问每个特定操作来停止,暂停,恢复或删除。因此,我想知道可能导致问题的原因,或者我以错误的方式实施了什么。

0 个答案:

没有答案