Java Executors.newFixedThreadPool如何停止同步方法上的所有活动线程
我有一个executor服务,它同时提交x个线程来完成一个长任务。我需要能够停止所有正在运行的当前线程,并防止队列任务启动。我试图实现一种方法来处理正在等待同步方法的停止线程,其中runnable将字符串列表传递回调用它的接口Java Executors.newFixedThreadPool如何停止同步方法上的所有活动线程,java,multithreading,executorservice,synchronized,Java,Multithreading,Executorservice,Synchronized,我有一个executor服务,它同时提交x个线程来完成一个长任务。我需要能够停止所有正在运行的当前线程,并防止队列任务启动。我试图实现一种方法来处理正在等待同步方法的停止线程,其中runnable将字符串列表传递回调用它的接口 @Override public synchronized void FilterResults(List<String> Results) { //System.out.println("Result fou
@Override
public synchronized void FilterResults(List<String> Results) {
//System.out.println("Result found: " + Results.size());
try {
Set<String> hs = new HashSet<>();
hs.addAll(Results);
Results.clear();
Results.addAll(hs);
for (String tempURL : Results) {
//System.out.println("Found url: " + tempURL);
if (!isCompleted(tempURL) && !isQueued(tempURL) && !isRunning(tempURL)) {
System.out.println("Added: " + tempURL + " to queue.");
queueLink(tempURL);
startNewThread(tempURL);
}
}
}catch(Exception e) {
}
return;
}
private synchronized void startNewThread(String seedURL) {
if (!isCompleted(seedURL) && !isRunning(seedURL) ) {
if (completedSize("") + runningSize() > 99) {
Stop();
}
String tempProxy = "";
String tempPort = "";
if (UseProxies) {
String Proxy = grabFreeProxy();
String[] splitProxy = Proxy.split(":");
tempProxy = splitProxy[0]; // 004
tempPort = splitProxy[1]; // 034556
}
//System.out.println("Proxy: " + tempProxy);
//System.out.println("Port: " + tempPort);
execService.submit(new Crawl(seedURL, this, tempProxy, tempPort, UseProxies));
removeFromQueue(url);
}
}
@Override
public Collection<String> Stop() {
try {
execService.shutdown();
if (execService.awaitTermination(45, TimeUnit.SECONDS)) {
System.out.println("task completed");
} else {
execService.shutdownNow();
}
} catch (InterruptedException e) {
}
return PROFILES;
}
The Runnable
public class Crawl implements Runnable{
public void run() {
while(!Thread.currentThread().isInterrupted() && shutdown == false) {
try {
//System.out.println(crawler.queueSize());
Thread.sleep(100);
Crawl(url);
}catch (InterruptedException e) {
Thread.currentThread().interrupt(); // set interrupt flag
}
}
public void crawl(){
try {
submitResults(urls); //Calls FilterResults()
} catch (InterruptedException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
Thread.currentThread().interrupt();
}
crawler.removeUsedProxy(Proxy + ":" + Port);
this.shutdown();
}
}
@覆盖
公共同步的无效筛选器结果(列出结果){
//System.out.println(“找到的结果:+Results.size());
试一试{
Set hs=新的HashSet();
hs.addAll(结果);
结果:清晰();
结果:addAll(hs);
for(字符串tempURL:Results){
//System.out.println(“找到的url:+tempURL”);
如果(!isCompleted(tempURL)&&!isQueued(tempURL)&&!isRunning(tempURL)){
System.out.println(“添加:“+tempURL+”到队列”);
队列链接(tempURL);
startNewThread(tempURL);
}
}
}捕获(例外e){
}
返回;
}
私有同步的void startNewThread(字符串seedURL){
如果(!isCompleted(seedURL)&&!isRunning(seedURL)){
如果(completedSize(“”+runningSize()>99){
停止();
}
字符串temproxy=“”;
字符串tempPort=“”;
如果(使用代理){
字符串Proxy=grabFreeProxy();
字符串[]splitProxy=Proxy.split(“:”);
tempProxy=splitProxy[0];//004
tempPort=splitProxy[1];//034556
}
//System.out.println(“代理:+temproxy”);
//System.out.println(“端口:+tempPort”);
submit(新爬网(seedURL、this、tempProxy、tempPort、UseProxies));
removeFromQueue(url);
}
}
@凌驾
公众收集站(){
试一试{
execService.shutdown();
if(执行服务等待终止(45,时间单位秒)){
System.out.println(“任务完成”);
}否则{
execService.shutdownNow();
}
}捕捉(中断异常e){
}
返回配置文件;
}
可运行的
公共类爬网实现可运行{
公开募捐{
而(!Thread.currentThread().isInterrupted()&&shutdown==false){
试一试{
//System.out.println(crawler.queueSize());
睡眠(100);
爬网(url);
}捕捉(中断异常e){
Thread.currentThread().interrupt();//设置中断标志
}
}
公共空间爬网(){
试一试{
submitResults(URL);//调用FilterResults()
}捕捉(中断异常e){
//TODO自动生成的捕捉块
//e、 printStackTrace();
Thread.currentThread().interrupt();
}
crawler.removeUsedProxy(代理+“:”+端口);
这是shutdown();
}
}
当我调用shutdown方法时,需要45秒以上的时间才能可靠地取消任务而不需要长时间的等待?随着线程的增加,这个数字会增加,而且由于所有线程都在阻塞等待提交结果,这可能需要一些时间。如果我手动取消任务,我不在乎是否存储了结果,我只需要able取消。有什么想法吗
更新我尝试过执行器服务#立即关闭。它不可靠
当涉及到终止仍被synchronized
方法阻止的任务时
看起来您需要使用,以防您不想等待并完成所有工作,您将收到一个包含未执行任务的列表。您可以使用(使用不同于45秒的参数)如果您想/需要提供一段时间等待任务完成。为什么不直接调用
shutdownow
呢?将其设置为小于45会使其他线程保持运行。