0

我在 excel 文件中有一些地方,每个点都有一个 lng 和 lat 坐标。

现在我尝试使用谷歌地图静态地图api为每个点创建一个静态地图。

我有两个组件,一个解析器和一个加载器。

Parser 用于读取 excel 文件,而 loaded 用于加载图块。

我让加载程序在单独的线程中运行。

public class Parser {
    private static Parser instance;
    private StaticMapLoader loader;

    private Parser(StaticMapLoader loader) {
        this.loader = loader;
    }

    public synchronized static Parser getInstance(StaticMapLoader loader) {
        if (instance == null) {
            instance = new Parser(loader);
        }
        return instance;
    }

    public void parse(String path) {
        List<Branch> result = new ArrayList<Branch>();

        InputStream inp;
        try {
            inp = new FileInputStream(path);
            Workbook wb = WorkbookFactory.create(inp);
            Sheet sheet = wb.getSheetAt(0);
            int rows = sheet.getLastRowNum();


            for(Row r : sheet.getRows){
                loader.addTask(r.type,r.name,r.x,r.y);
            }
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
//      Branch bc = new Branch("网点1", null, null);
        return result;
    }

}

装载机:

public class StaticMapLoader extends Thread {
    private final static Logger log = Logger.getLogger(StaticMapLoader.class);

    private List<Task> tasks = new ArrayList<Task>();
    private String tilePath;

    private boolean running = false;


    public StaticMapLoader(String saveDir) {
        this.tilePath = saveDir;
    }


    @Override
    public void run() {
        while (running) {
            log.debug("run " + tasks.size());
            if (tasks.size() > 0) {
                Task t = tasks.get(0);
                if (t != null && t.status == Status.waiting) {
                    tasks.remove(0);
                    t.status = Status.running;
                    downLoad(t);
                }
            }

        }
    }

    private void downLoad(Task t) {
        log.debug(String.format("load data for " + t.toString()));
        //down tiles and save 
        t.status=Status.success;
    }

    public void addTask(String type, String name, double x, double y) {
        log.debug(String.format("add task of :%s,%s", type, name));
        tasks.add(new Task(type,name,x,y));
    }

    public void startRunning() {
        running = true;
        this.start();
    }

    public void stopRunning() {
        running = false;
        this.interrupt();
    }

    class Task {
        Status status = Status.waiting;

        String type, name;
        double x,y;

        Task(String type, String name, double x,double y) {
            this.type = type;
            this.name = name;
            this.xian = xian;
            this.x = x;
            this.y = y;
        }
    }

    enum Status {
        waiting, running, fail, success
    }
}

该过程相当简单,StaticMapLoader具有ArrayList. 在Parser解析记录(位置)时,它将被扔到列表中。

加载器将迭代列表并下载数据。

但是我在这里遇到了一个奇怪的问题:

@Override
public void run() {
    while (running) {
        log.debug("run " + tasks.size());
        if (tasks.size() > 0) {
            Task t = tasks.get(0);
            if (t != null && t.status == Status.waiting) {
                tasks.remove(0);
                t.status = Status.running;
                downLoad(t);
            }
        }

    }
}

上面的代码运行,我会得到这样的日志:

run 1
add task of ..
run 2
add task of ...

但是,如果我评论日志行,downLoad将永远不会被调用,我会得到:

run 1
run 2
......

看来这可能是由 Thread 引起的,我错过了什么吗?

顺便说一句,上面的代码在HttpServlet上下文中运行,我这样开始它们:

@Override
public void init() throws ServletException {
    super.init();

    try {
        URL fileUrl = getServletContext().getResource(getInitParameter("xlsxFile"));
        URL tilePath = getServletContext().getResource(getInitParameter("tilePath"));

        StaticMapLoader loader = new StaticMapLoader(tilePath.getPath());
        loader.startRunning();


        Parser.getInstance(loader).parse(fileUrl.getPath());

    } catch (MalformedURLException e) {
    }
}
4

0 回答 0