Java定时器只触发一次(服务器唯一的问题)

好吧,这是一个奇怪的,它似乎不是一个编码问题。 我有我的家用电脑和我的服务器电脑上安装Intellij(都运行Windows专业版)。 我在遥远的地方并肩而行。 无论是与Intellij打开和两个相同的副本和粘贴代码。 在我的家用电脑上,这个代码完美的工作,每60秒会启动一次。 但在服务器计算机上,它会一次点燃,而且不会再次启动。 我已经把它打包成一个jar子,运行jar子和相同的东西,它运行一次,永远不会再运行。 这是代码。

public class BackupTask extends TimerTask { private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){ @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH_mm_ss"); } }; public void run() { try { File src = new File("C:\\Users\\justi\\Desktop\\Server\\Saved"); File dest = new File("\\\\READYSHARE\\USB_Storage\\Backups\\" + df.get().format(Calendar.getInstance().getTime())); if(!dest.exists()){ dest.mkdir(); } copyFolder(src, dest); }catch(Exception e){ System.out.println("Error: " + e); } } public static void copyFolder(File src, File dest) throws IOException{ if(src.isDirectory()){ //if directory not exists, create it if(!dest.exists()){ dest.mkdir(); } //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{ //if file, then copy it //Use bytes stream to support all file types InputStream in = new FileInputStream(src); OutputStream 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); } in.close(); out.close(); } } } 

AutoBackup.java

 public class AutoBackup { // Timer timer; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private final int TIME_BETWEEN_SAVES = 60; public AutoBackup(){ final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(new BackupTask(), 10, TIME_BETWEEN_SAVES, TimeUnit.SECONDS); } public static void main(String[] args) { new AutoBackup(); // Timer timer = new Timer(); // timer.schedule(new BackupTask(), 1000, 60 * 1000); } } 

这个程序只是一个非常简单的复制和粘贴从一个位置到另一个按计划的时间间隔。 我也尝试运行Intellij作为pipe理员,我只是出于为什么会发生这种想法。 服务器电脑有一个核心i5-4690k,Micro ITX技嘉超耐用GA-H97N-WIFI H97主板与16演出公羊。 让我知道是否有任何其他信息将有所帮助。

你所描述的非常奇怪,但是当你的代码可能失败的时候,我会遇到一个例子。 让我详细描述一下。 您首先创建线程池大小= 1的新的调度执行程序:

 Executors.newScheduledThreadPool(1); 

这个单线程将被用来执行你的runnables。 然后你计划以固定的速度运行,10秒后先运行,然后每60秒运行一次:

 scheduler.scheduleAtFixedRate(new BackupTask(), 10, 60, TimeUnit.SECONDS); 

现在,因为执行程序中只有一个线程可以运行可运行的程序,所以当您的BackupTask因为任何原因挂起,或者可能执行更长的时间时,只要第一个执行完成,下一次执行就会被延迟。 你正在做网络备份,所以问题可能与网络有关。 举个例子 – 执行close()可能会导致代码等待网络超时(取决于超时值的长度),或者在同一个场景中执行write(..)。

我会建议在代码中放一些调试语句(请参阅下面的代码)。 我知道这可能会在应用程序控制台中产生一些垃圾,但是如果你不想远程调试,这可能是唯一的方法来找出代码中的错误。

 public static void copyFolder(File src, File dest) throws IOException{ if (src.isDirectory()) { //if directory not exists, create it if(!dest.exists()){ System.out.println("Creating directory " + dest); dest.mkdir(); System.out.println("Created directory "); } for (String file : src.list()) { File srcFile = new File(src, file); File destFile = new File(dest, file); System.out.println("Copying " + srcFile + " to " + destFile); copyFolder(srcFile,destFile); System.out.println("Copied " + srcFile + " to " + destFile); } }else{ InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest); byte[] buffer = new byte[1024]; System.out.println("Writing file " + src + " to " + dest); int length; //copy the file content in bytes while ((length = in.read(buffer)) > 0){ out.write(buffer, 0, length); } System.out.println("Closing file " + src); in.close(); System.out.println("Closing file " + dest); out.close(); System.out.println("Writing file " + src + " to " + dest + " is done"); } } 

另外,关于你的代码的几点意见:

您的BackupTask扩展了TimerTask。 这是不必要的。 它足以实现Runnable。

从流中读写时,应该始终确保在finally节中关闭资源,或使用资源尝试(从Java 7向上)。 否则,你可能会留下永远打开的文件。

 InputStream in = null; OutputStream out = null; byte[] buffer = new byte[1024]; int length; try { in = new FileInputStream(src); out = new FileOutputStream(dest); while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } }