在循环

时间:2016-10-28 05:00:00

标签: java multithreading concurrency

我的代码有以下几种方法:

  • downloadFile() - 从ftpserver下载文件

  • processFile() - 逐行读取文件并处理

  • sendSMS() - 向供应商发送短信已处理的记录数。

processFile方法读取每一行,构建一个URL字符串并点击URL。为了使流程更快,我使用了线程概念。

//snippet in processFile method
while ((sCurrentLine = br.readLine()) != null) {
    String[] arr = sCurrentLine.split("\t");

    if (//some condition) {
        String url = //build url from the current line  
        Thread t = new Thread(new MyClass(url));
        t.start();
    } 
}

public MyClass(String strUrl) {
    this.strUrl = strUrl;
}

public void run() {
    urlHit(strUrl);//call function to hit current URL
}

现在我担心的是sendSMS方法只有在所有网址都被点击后才会被调用。

我尝试使用join方法,该方法工作正常,但它与不使用线程一样好。

3 个答案:

答案 0 :(得分:1)

使用ExecutorServiceinvokeAll API。

请参阅此帖子关于invokeALl()

的使用情况

How to use invokeAll() to let all thread pool do their task?

替换

Thread t = new Thread(new MyClass(url));

Callable任务并将您的Callable任务提交至ExecutorService

按照其中一个可用选项处理完所有网址后,请调用sendSMS()方法。

答案 1 :(得分:0)

您需要应用同步,并且有多种方法可以在java中应用同步。您可以使用send {s}等待的wait()notify(),直到收到有关网址被点击的通知为止。 查看示例here以帮助您。

答案 2 :(得分:0)

在这种情况下使用执行程序是一个好主意,可以限制并发执行的线程数。您实现目标的步骤如下:

  • 构建 Callable 的列表,每个人都会创建URL并点击构建的URL。
  • 创建一个线程池执行程序,并使用 Callable 对象列表作为参数调用 invokeAll
  • 一旦invokeAll返回,您可以循环返回 Callable 的列表,并在需要时调用 get()来获取结果,例如确认URL是击中成功。

例如,以下内容类似于用于创建 Callable 列表的代码:

List<Callable> createUrlAndHit = new ArrayList<Callable>();
while ((sCurrentLine = br.readLine()) != null) {
    String[] arr = sCurrentLine.split("\t");

    if (//some condition) {
        createUrlAndHit.add(new Callable(){
           //Add your logic here...., or create a specific implementation of callable to instantiate with your url
        });
    } 
}

下一步是invokeAll:

ExecutorService executor = Executors.newFixedThreadPool(...);
List<Future<Callable>> futures = executor.invokeAll(createUrlAndHit);
//Loop on results and send SMS
for(Callable c : futures){
  //send sms..
}