2025-05-25

問題:寫出這個工具的意義在於我運行一個需要長時間執行的程序,如單線程爬蟲。在網絡出現中斷的或網站丟包情況下,程序會拋出socketexception 和sockettimeoutexception。程序會中斷。(再此隻是提出一種假設)


解決方案:


Java 並不能像C#一樣對windows的進程進行監控(資料說這是跨平臺原因)。因此沒有api 提供對其他進程的監控(如果在此您有其他辦法,希望您給出寶貴建議)。所以很多人都是通過對文件的加鎖,來判斷程序是否在運行。


一、判斷當前程序是否正在運行


在此我參考瞭:


java 對文件的加鎖。


這裡的思路是:


1、 在要監視寫的程序中(這裡假設為爬蟲)對一個用來判斷程序是否運行的文件(自定義,無實際意義。隻是一個空文件)對文件進行加鎖。


2、 在守護程序中寫瞭簡單的 循環來實現按時探測。這裡面比如說20秒。


3、  如果程序確實在運行(即文件不能再被加鎖,因為已被鎖),那麼證明程序確實在運行,否則,如果程序出現瞭網絡異常而中斷,那麼runtime重新調用該程序。


(演示代碼如下:註意不要忘瞭在爬蟲程序中需要對文件進行加鎖)。這樣才有效。


演示代碼:


 


 


import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;


import data.BaseDataofConfiguration;


public class ThreadKeepTools {
    /** *//**
    * 通過文件鎖來判斷程序是否正在運行
    * @return 如果正在運行返回true,否則返回false
    */
    private static boolean isRunning(String fileLockPath)
    {
        boolean rv=false;
        try {
            //
            String os_name=System.getProperty(“os.name”);
            //指定文件鎖路徑
            String path=null;
            if(os_name.indexOf(“Windows”)>-1)
            {
                //如果是Windows操作系統
                path=System.getProperty(“user.home”)+System.getProperty(“file.separator”);
            }
            else
            {
                path=”/usr/temp/”;
            }
            File dir=new File(path);
            if(!dir.exists())
            {
                dir.mkdirs();
            }
            //程序名稱
            String applicationName=”run.bat”;
            RandomAccessFile fis = new RandomAccessFile(fileLockPath,”rw”);
            FileChannel lockfc = fis.getChannel();
            FileLock flock = lockfc.tryLock();
            if(flock == null) {
                System.out.println(“程序正在運行.”);
                rv=true;
               
            }else {
                flock.release();
            }
           
        
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return rv;
    }
   
    public static void ExcuteThread() throws InterruptedException{
        String strFilePath=BaseDataofConfiguration.baseUrlOfPro+”testThread.txt”;
        String strBatPath=BaseDataofConfiguration.baseUrlOfPro+”run.bat”;
        strBatPath=strBatPath.replaceFirst(“/”, “”);
        while(true){
            System.out.println(“strFilePath:”+strFilePath);
        boolean RunOrNOT=isRunning(strFilePath);
        System.out.println(“RunOrNot:”+RunOrNOT);
       
        if(!RunOrNOT){
            try {
                System.out.println(“開始執行程序!”);
           
                Runtime.getRuntime().exec(“cmd /k start “+strBatPath);
                System.out.println(“strbatpath:”+strBatPath);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
           
        }else {
            Thread.sleep(6000);
        }
        Thread.sleep(10000);
       
        }
    }
    public static void main(String[] args) {
        try {
            ExcuteThread();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
     &nbs

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *