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();
    }
}

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

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

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);
}
}