我正在用Java控制台应用程序制作类似Web爬网程序的东西,我得到了一个实现可运行接口的类,并且在方法运行中,我得到了我想做的操作(例如一个for循环,该循环迭代每个URL作为输入并在所有计算中进行)。
我希望每个迭代都由不同的线程完成。因此,我使用executorsservice(线程数与url数相同)创建了一个线程池,并使用了synced关键字,一次只允许一个线程在其中执行计算块。
但是如何确保同一线程不会再次在代码块内重新进入?如果需要的话,我会在稍后发布代码段。
谢谢。
我得到的输出如下:
我正在用每个URL搜索2个关键字。这个例子是1个网址和2个关键字。
当前线程:pool-1-thread-2 ----------------- 当前线程:pool-1-thread-1 -----------------
标题:维基百科,免费的百科全书 网址:https://en.wikipedia.org Times关键字“免费找到”:41
标题:维基百科,免费的百科全书 网址:https://en.wikipedia.org Times关键字“免费找到”:41
标题:维基百科,免费的百科全书 网址:https://en.wikipedia.org 找到Times关键字Wikibooks:82
标题:维基百科,免费的百科全书 网址:https://en.wikipedia.org 找到Times关键字Wikibooks:82
我认为我以某种方式做到了,但是现在我面临着新的问题,例如请参阅运行方法内的注释。
public class KeywordCounter {
private List keylist;
private List weblist;
public KeywordCounter(List keywordlist, List listWebsites) {
this.keylist = new ArrayList(keywordlist);
this.weblist = new ArrayList(listWebsites);
}
public void threadCreate(List klist, List listWebsites) {
// TODO Auto-generated method stub
ExecutorService executor = Executors.newFixedThreadPool(2);
for (int w = 0; w < this.weblist.size(); w++) {
executor.execute(new Runnable() {
private List keylist = new ArrayList(klist);
private List weblist = new ArrayList(listWebsites);
@Override
public synchronized void run() {
System.out.println("Current Thread: " + Thread.currentThread().getName().toString() + " ")
// Computations i want one thread inside here each time but i think both threads are entering same time cause i saw 4 results instaid of 2.
//Also i want inside here to pass the w variable of the for loop, cause i need it for further computations how i can achieve this?.
});
}
}
}
答案 0 :(得分:0)
在编写一些代码之前,很难说,但您的方法正确。也尝试使用BlockingQueue。如果您有多个线程,并且队列中每个线程都同时工作,则可以确定它不会是循环。 当然,如果您的线程1在1毫秒内工作,线程2在1分钟内工作,那么...没有任何阻塞。
尝试使用wait/notify also
答案 1 :(得分:0)
如果您有两个URL,那么您将有两个线程。一个线程用于一个URL,另一个线程用于另一个URL。两者是同时启动的。
现在,我们有一段代码必须不能并行执行,而所有其他代码必须并行执行。这段代码必须被执行!我们将这段代码称为“关键部分”。
要在Java中将某个部分标记为关键,可以使用synced语句:
01 mulithread-code
02 mulithread-code
03 mulithread-code
04 synchronized {
05 critical code
06 critical code
07 }
08 mulithread-code
09 mulithread-code
10 mulithread-code
有两个线程,加入行04
的第一个线程将立即启动。第二个线程将等待。第一个线程将完成从第05
行到第06
行的所有工作。
然后魔术发生了:第一个线程离开行07
时,第二个线程停止了等待并继续他的工作:第二个线程将开始执行05
行,然后执行{{1 }}。
答案 2 :(得分:0)
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Client2 {
public static void main(String[] args) {
ExecutorService pool= Executors.newFixedThreadPool(5);
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<String>(pool);
List<String> url=Arrays.asList("www.goole.in","www.abc.com");
for(int i=0;i<url.size();i++) {
completionService.submit(new MyCallable(url.get(i)));
}
for(int i=0;i<url.size();i++) {
try {
Future<String> s=completionService.take();
System.out.println(s.get());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class MyCallable implements Callable<String>{
String Url;
public MyCallable(String url) {
this.Url=url;
}
@Override
public String call() throws Exception {
//process the URL
return Url+" Processed.";
}
}