这段代码线程安全吗?

时间:2017-10-07 22:50:13

标签: java executorservice

private static final Word2Vec word2vectors = getWordVector();

    private static Word2Vec getWordVector() {
        String PATH;
        try {
            PATH = new ClassPathResource("models/word2vec_model").getFile().getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        log.warn("Loading model...");
        return WordVectorSerializer.readWord2VecModel(new File(PATH));
    }

        ExecutorService pools = Executors.newFixedThreadPool(4);
        long startTime = System.currentTimeMillis();
        List<Future<?>> runnables = new ArrayList<>();
        if (word2vectors != null) {
            for (int i = 0; i < 3000; i++) {
                MyRunnable runnable = new MyRunnable("beautiful", i);
                runnables.add(pools.submit(runnable));
            }
        }
        for(Future<?> task: runnables){
            try {
                task.get();
            }catch(InterruptedException ie){
                ie.printStackTrace();
            }catch(ExecutionException ee){
                ee.printStackTrace();
            }
        }
        pools.shutdown();

static class MyRunnable implements Runnable{
        private String word;
        private int count;
        public MyRunnable(String word, int i){
            this.word = word;
            this.count = i;
        }

        @Override
        public void run() {
                Collection<String> words = word2vectors.wordsNearest(word, 5);
                log.info("Top 5 cloest words: " + words);
                log.info(String.valueOf(count));
        }
    }

word2vectors.wordsNearest()是来自公共库的方法。我打算让4个线程同时执行该方法来加速进程。这个线程安全吗?

1 个答案:

答案 0 :(得分:2)

如果满足以下条件,您的代码段将是线程安全的:

  1. word2vectors.wordsNearest(...)调用是线程安全的
  2. word2vectors数据结构由当前线程创建并初始化。
  3. 没有任何内容会更改pools.execute调用和计算完成之间的数据结构。
  4. 如果wordsNearest没有查看其他数据结构,并且它没有更改word2vectors数据结构,那么它是合理的假设它是线程安全的。但是,唯一可以确定的方法是分析它

    但值得注意的是,您只向执行人提交了一项任务。由于每个任务都由单个线程运行,因此您的代码只能有效地使用一个线程。要利用多线程,您需要将单个大任务拆分为多个小而独立的任务;例如将10,000重复循环放在执行调用之外...