hxboss
2015-04-09 08:51
采纳率: 100%
浏览 4.3k
已采纳

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

业务逻辑:

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

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

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

请问这种要怎么实现。。

是不是用到

ExecutorService exec = Executors.newFixedThreadPool(5);

java.util.concurrent.Future;

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

6条回答 默认 最新

  • danielinbiti 2015-04-09 09:58
    已采纳

    可以类似下面这样

     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();
        }
    }
    
    
    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • Tiger_Zhao 2015-04-09 09:28

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

    评论
    解决 无用
    打赏 举报
  • hxboss 2015-04-10 00:23

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

    评论
    解决 无用
    打赏 举报
  • hxboss 2015-04-10 00:25

    cdLatch.await();

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

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

    评论
    解决 无用
    打赏 举报
  • hxboss 2015-04-10 00:25

    哦 有个break

    评论
    解决 无用
    打赏 举报
  • 毕小宝 2015-04-10 01:09

    基本思路是:任务执行类携带一个控制信息(标识是否有任务完成目标搜索),每次匹配规则之前,先检查该标识,如果非真,则进行规则匹配,若果该任务找到了目标,则修正该标识为真,通知其他任务结束。
    示例代码如下,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);
    }
    }

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题