java线程池当其中一个线程算出结果,终止全部线程

问题描述

java线程池当其中一个线程算出结果,终止全部线程

业务逻辑:

一个大型社区,每一秒有上千人在提交留言,提交的留言将经过,上万条的正则表达式的过滤,没有匹配任何规则的,才保存到系统,否则提示用户,您录入的内容不合法。

我是这样想的,把这上万条正则表达式,拆分成2000条一组,开一个5个线程的线程池,每个线程将负责其中2000个规则的匹配。

每条留言提交时,将由这5个线程,去判断是否有匹配的规则,如果其中一个线程匹配到了规则,将结束其他4个线程的任务,返回给用户结果。

请问这种要怎么实现。。

是不是用到

ExecutorService exec = Executors.newFixedThreadPool(5);

java.util.concurrent.Future;

解决方案

可以类似下面这样

 import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

public class TestThread {
    /**
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {

        String c = "评论1";
        TxtClass tx = new TxtClass(c);
        CountDownLatch cdLatch = new CountDownLatch(5);
        Thread tr = new CRThread(1,tx,cdLatch);//1表示第一个
        Thread tr2 = new CRThread(2,tx,cdLatch);
        Thread tr3 = new CRThread(3,tx,cdLatch);
        Thread tr4 = new CRThread(4,tx,cdLatch);
        Thread tr5 = new CRThread(5,tx,cdLatch);

        tr.start();
        tr2.start();
        tr3.start();
        tr4.start();
        tr5.start();
        cdLatch.await();        

        System.out.println("都执行完了,结果["+tx.isFind() + "]");
    }

}
class TxtClass{
    private String c = "";
    private boolean isFind = false;
    public TxtClass(String c){
        this.c = c;
    }
    public boolean isFind() {
        return isFind;
    }
    public void setFind(boolean isFind) {
        this.isFind = isFind;
    }
    public String getC() {
        return c;
    }

}
class RegClass{//校验规则
    private static RegClass rc = new RegClass();
    public static RegClass getInstance(){
        return rc;
    }
    private ArrayList<String> list = new ArrayList();
    public RegClass(){//初始化规则
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("s");
        list.add("1");
        list.add("评");
        list.add("a");
        list.add("b");
        list.add("r");
    }
    public boolean isContains(int index,String c){
        if(list.size()>index){
            return c.indexOf(list.get(index))>=0;
        }else{
            return false;
        }
    }
}
class CRThread extends Thread{
    private int startNum = 0;
    private TxtClass txtClass;//留言内容
    private CountDownLatch cdLatch;
    private int oneLength = 2000;//一个线程校验的长度
    public CRThread(int i,TxtClass txtClass,CountDownLatch cdLatch){
        super();
        this.startNum = i;
        this.txtClass = txtClass;
        this.cdLatch = cdLatch;
    }
    @Override
    public void run() {
        boolean f = false;
        int nums = 0;
        for(int i=0;i<oneLength;i++){
            nums = (startNum-1)*oneLength+i;
            System.out.println("thread-"+startNum+"-["+nums+"]");
            f=RegClass.getInstance().isContains(nums, txtClass.getC());
            if(f){
                txtClass.setFind(true);
            }
            if(txtClass.isFind()){
                break;
            }
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("thread-"+startNum+"-结束["+nums+"]");
        this.cdLatch.countDown();
    }
}

解决方案二:

谢谢楼上两位的回复
但是每次都 Thread tr = new CRThread(1,tx,cdLatch); 这样新开线程,效率会不会低一点呢
其实我是想用一个线程池,专门处理这个内容检查,一个评论扔到这个池里面,池经过多线程匹配计算,抛出结果

解决方案三:

"每一秒有上千人在提交留言"
既然同时要进行这么多的检查,1个留言用5个线程各自处理2000个匹配,不如这5个线程取处理5个留言的10000个匹配简单(之间跳出自己的循环即可)。
反正两个方案都是平均1个留言做5000次匹配。

解决方案四:

cdLatch.await();

System.out.println("都执行完了,结果["+tx.isFind() + "]");

这样一await,是不是全部线程都要执行完,才会给结果的?
如果其中一个线程已经算出结果了,其他几个会自动听下来吗

解决方案五:

哦 有个break

解决方案六:

基本思路是:任务执行类携带一个控制信息(标识是否有任务完成目标搜索),每次匹配规则之前,先检查该标识,如果非真,则进行规则匹配,若果该任务找到了目标,则修正该标识为真,通知其他任务结束。
示例代码如下,ControlInfo是控制信息,Task是任务类,Test是测试函数(定义控制信息和匹配规则,使用线程池提交任务)。
/**

  • 全局控制控制信息
  • 每个任务都关联一个该属性,任务之前之前先检查该标识,完成之后修正该标识
  • @author bh
    */
    public class ControlInfo {
    private boolean isShouldFinished;
    public boolean isShouldFinished() {
    return isShouldFinished;
    }
    public void setShouldFinished(boolean isShouldFinished) {
    this.isShouldFinished = isShouldFinished;
    }
    }
    import java.util.List;

    /**

    • 任务类处理规则:每次规则校验时先判断是否有其他线程找到
    • 如果有其他线程已经完成,则结束;否则自己查找,找到通知其他线程
    • @author bh
      */
      public class Task implements Runnable{
      private ControlInfo controlInfo;
      private List rules;

    public Task(ControlInfo controlInfo,List rules){
    this.controlInfo = controlInfo;
    this.rules = rules;
    }

    @Override
    public void run() {
    //遍历规则,进行校验
    for(String rule:rules){
    //操作之前先判断是否有其他线程找到了,如果找到了就结束
    synchronized(controlInfo){
    if(!controlInfo.isShouldFinished()){
    //TODO 判断规则处理:校验规则
    if(rule.equals("")){
    //找到了,通知其他任务,结束
    controlInfo.setShouldFinished(true);
    }
    }else{
    //有任务已经完成,则结束规则查找
    return;
    }
    }
    }
    }
    }
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;

public class Test {
public static void main(String[] args) {
//开启一个线程池
ExecutorService exec = Executors.newFixedThreadPool(5);
//定义需校验的规则
List r1 = null;
List r2 = null;
List r3 = null;
List r4 = null;
List r5 = null;
//创建一个控制对象
ControlInfo controlInfo = new ControlInfo();
//创建N个任务,第二个参数是规则
Task t1 = new Task(controlInfo,r1);
Task t2 = new Task(controlInfo,r2);
Task t3 = new Task(controlInfo,r3);
Task t4 = new Task(controlInfo,r4);
Task t5 = new Task(controlInfo,r5);
//线程池执行任务
exec.execute(t1);
exec.execute(t2);
exec.execute(t3);
exec.execute(t4);
exec.execute(t5);
}
}

时间: 2024-11-16 13:22:30

java线程池当其中一个线程算出结果,终止全部线程的相关文章

线程池就好像一个池子,可以容纳各种液体

线程池就好像一个池子,可以容纳各种液体.     在<windows核心编程>中提及了win2000的新的线程池概念,以及一个新函数,很好用,但vc6.0不支持该函数(MSDN上有),可以直接调用库里的函数,看了该函数,应该对线程池有很好的了解.我曾作了个测试:     typedef   VOID   (WINAPI   *WAITORTIMERCALLBACK)(PVOID,BOOLEAN);         typedef   BOOL   (FAR   PASCAL   *   FUN

(JAVA新手)请教大家一个关于求出数组中最大最小值的问题;

问题描述 我的代码是这样的,可是不能打印输出最小值,publicclassShuZu{publicstaticvoidmain(String[]args){intscore[]={1,23,3,4,5,5623,5};intmax=0;intmin=0;max=min=score[0];for(intx=0;x<score.length;x++){if(score[x]>max){max=score[x];}if(score[x]<min);{min=score[x];}}System.

Linux线程池使用

一.线程池概述            线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线       程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中.如果某个线程在托管代码中空闲(如正在等待       某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙.如果所有线程池线程都始终保持繁忙,但队列中包含挂起       的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值.超

100行Java代码构建一个线程池

在现代的操作系统中,有一个很重要的概念――线程,几乎所有目前流行的操作系统都支持线程,线程来源于操作系统中进程的概念,进程有自己的虚拟地址空间以及正文段.数据段及堆栈,而且各自占有不同的系统资源(例如文件.环境变量等等).与此不同,线程不能单独存在,它依附于进程,只能由进程派生.如果一个进程派生出了两个线程,那这两个线程共享此进程的全局变量和代码段,但每个线程各拥有各自的堆栈,因此它们拥有各自的局部变量,线程在UNIX系统中还被进一步分为用户级线程(由进程自已来管理)和系统级线程(由操作系统的调

Java代码构建一个线程池_JSP编程

在现代的操作系统中,有一个很重要的概念――线程,几乎所有目前流行的操作系统都支持线程,线程来源于操作系统中进程的概念,进程有自己的虚拟地址空间以及正文段.数据段及堆栈,而且各自占有不同的系统资源(例如文件.环境变量等等).与此不同,线程不能单独存在,它依附于进程,只能由进程派生.如果一个进程派生出了两个线程,那这两个线程共享此进程的全局变量和代码段,但每个线程各拥有各自的堆栈,因此它们拥有各自的局部变量,线程在UNIX系统中还被进一步分为用户级线程(由进程自已来管理)和系统级线程(由操作系统的调

几种java线程池的实现算法分析

1. 前言 本文发表与infoq,因版权属于个人顾再此转载. 在阅读研究线程池的源码以前,只知道如何使用,不了解其内部实现的具体细节,一直感觉是非常高深的技术,研究后才发现,线程池的实现是如此精巧.本文从技术角度分析了线程池的本质原理和组成,同时分析了JDK.Jetty6.Jetty8.Tomcat的源码实现,对于想了解线程池本质.更好的使用线程池或者定制实现自己的线程池的业务场景具有一定指导意义. 2. 使用线程池的意义 l 复用:类似WEB服务器等系统,长期来看内部需要使用大量的线程处理请求

Java线程池管理及分布式Hadoop调度框架搭建

多线程是程序员面试时常常会面对的问题,对多线程概念的掌握和理解水平,也常常被用来衡量一个人的编程实力.不错,普通的多线程已经不容易了,那么当多线程碰到"大象"又会产生什么样的火花?这里我们为大家分享上海创行科技技术总监严澜的博文--Java线程池管理及分布式Hadoop调度框架搭建. 平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发工程师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式框架

如何搭建JAVA线程池管理及分布式HADOOP调度框架教程

平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式框架让大家从单线程开发快速转入多线程开发,这确实是个比较难搞的工程. 那具体什么是线程呢?首先看看进程是什么,进程就是系统中执行的一个程序,这个程序可以使用内存.处理器.文件系统等相关资源.例如 QQ软件.eclipse.tomcat等就是一个exe程序,运行启动起来就是一个进程.为什么需要多线程?

管理Java线程池及搭建分布式Hadoop调度框架

平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发工程师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式框架让大家从单线程开发快速转入多线程开发,这确实是个比较难搞的工程. 那具体什么是线程呢?首先看看进程是什么,进程就是系统中执行的一个程序,这个程序可以使用内存.处理器.文件系统等相关资源.例如QQ软件.Eclipse.Tomcat等就是一个exe程序,运行启动起来就是一个进程.为什么需要多线程?如