Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
线程管理器Java的多线程实现_Java_Multithreading - Fatal编程技术网

线程管理器Java的多线程实现

线程管理器Java的多线程实现,java,multithreading,Java,Multithreading,我想逐行阅读excel工作表,每行的特定单元格包含URL。我需要通过程序访问该网站来处理这些URL。由于在单线程模型中连续访问每个单元的速度非常慢,因此我计划这样做: Step-1: Read excel sheet's cell of nth row. Step-2: nThreads++ Step-3: if nThreads==MAX_NO_OF_THREADS, sleep till one of the threads is finished. else Instant

我想逐行阅读excel工作表,每行的特定单元格包含URL。我需要通过程序访问该网站来处理这些URL。由于在单线程模型中连续访问每个单元的速度非常慢,因此我计划这样做:

Step-1: Read excel sheet's cell of nth row.
Step-2: nThreads++
Step-3: if nThreads==MAX_NO_OF_THREADS, sleep till one of the threads is finished.
        else Instantiate a thread to process the URL of that cell.
Step-4: Goto 1.
要实现这一点,我需要以下几点:

1-一些创建线程池的方法。我可以使用线程对象数组进行创建。但是我更喜欢更好的选择

2-一个管理线程,它执行从池中提取线程的任务,处理它们的工作并休眠,直到有一个线程可以执行该任务


那么我有什么选择呢?

更容易将其视为限制并发任务的数量。这意味着使用需要输入的可运行项,并且需要知道何时停止运行。此外,您还需要知道所有任务何时完成,以指示所有工作何时完成

我能想到的这个问题的最简单解决方案如下所示

import java.net.URL;
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class Q21512025 {

public static void main(String[] args) {

    ExecutorService executor = Executors.newCachedThreadPool(); 
    try {
        new Q21512025(executor, 5).readCells();
    } catch (Exception e) {
        e.printStackTrace();
    }
    executor.shutdownNow();
}

private int maxTasks;
private ExecutorService executor;
private CountDownLatch finished;
private LinkedBlockingQueue<ExcellUrlCell> q;

public Q21512025(ExecutorService executor, int maxTasks) {
    this.executor = executor;
    this.maxTasks = maxTasks;
    finished = new CountDownLatch(maxTasks);
    q = new LinkedBlockingQueue<ExcellUrlCell>();
}

public void readCells() throws Exception {

    for (int i = 0; i < maxTasks; i++) {
        executor.execute(new ExcellUrlParser(q, finished));
    }
    ExcellReader reader = new ExcellReader(getExampleUrls(10));
    while (reader.hasNext()) {
        q.add(reader.next());
    }
    for (int i = 0; i < maxTasks; i++) {
        q.add(new ExcellUrlCell(null));
    }   
    System.out.println("Awaiting excell url cell tasks.");
    finished.await();
    System.out.println("Done.");
}

private URL[] getExampleUrls(int amount) throws Exception {

    URL[] urls = new URL[amount];
    for (int i = 0; i < amount; i++) {
        urls[i] = new URL("http://localhost:" + (i + 2000) + "/");
    }
    return urls;
}

static class ExcellUrlParser implements Runnable {

    private CountDownLatch finished;
    private LinkedBlockingQueue<ExcellUrlCell> q;

    public ExcellUrlParser(LinkedBlockingQueue<ExcellUrlCell> q, CountDownLatch finished) {
        this.finished = finished;
        this.q = q;
    }
    @Override
    public void run() {

        try {
            while (true) {
                ExcellUrlCell urlCell = q.take();
                if (urlCell.isFinished()) {
                    break;
                }
                processUrl(urlCell.getUrl());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            finished.countDown();
        }
    }

    private void processUrl(URL url) {
        try { Thread.sleep(1); } catch (Exception ignored) {}
        System.out.println(url);
    }

}

static class ExcellReader implements Iterator<ExcellUrlCell> {

    private URL[] urls;
    private int index;

    public ExcellReader(URL[] urls) {
        this.urls = urls;
    }

    @Override
    public boolean hasNext() {
        return (index < urls.length);
    }

    @Override
    public ExcellUrlCell next() {
        ExcellUrlCell urlCell = new ExcellUrlCell(urls[index]);
        index++;
        return urlCell;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }

}

static class ExcellUrlCell {

    private URL url;

    public ExcellUrlCell(URL url) {
        this.url = url;
    }

    public URL getUrl() {
        return url;
    }

    public boolean isFinished() {
        return (url == null);
    }
}
}
import java.net.URL;
导入java.util.Iterator;
导入java.util.concurrent.CountDownLatch;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.LinkedBlockingQueue;
公共类Q21512025{
公共静态void main(字符串[]args){
ExecutorService executor=Executors.newCachedThreadPool();
试一试{
新Q21512025(executor,5).readCells();
}捕获(例外e){
e、 printStackTrace();
}
执行者。关机现在();
}
私有任务;
私人遗嘱执行人;
私人倒计时结束;
私有链接锁定队列q;
公共Q21512025(执行器服务执行器,int maxTasks){
this.executor=执行人;
this.maxTasks=maxTasks;
完成=新的倒计时锁存器(maxTasks);
q=新的LinkedBlockingQueue();
}
public void readCells()引发异常{
对于(int i=0;i
线程管理器怎么样?我只是碰巧在SourceForge.net上管理了几个Fork/Join服务器。您可以将请求分解为单独的组件,并在单独的线程池中运行每个组件,或者您可以将请求动态分解为相同的任务,以便在线程池中执行


这两种开源产品已经存在多年,可以为您节省很多精力。

Use。不要试图自己创建一个池。同步是一件棘手的事情。@zapl酷!但是负责委派任务和等待的管理线程是什么呢?这是一个由参与者建模的完美任务。考虑使用像AKKA这样的事情。@ RAPHW,我宁愿使用标准J2SE UTLS而不是第三方库。这里最大的架构错误是使用同步I/O来获取URL。每个HTTP请求不需要一个线程。请参见
AsyncHttpClient