java - 如何在Java代码中启动一组线程

标签 java multithreading

我有一个问题。

我有 10000 个字符串,我想对每个字符串执行一些操作。我想并行化此操作,以使总执行时间可以接受。

我决定创建线程。特别是,每 10 个字符串我启动 10 个线程。对于每个线程,我将结果保存在列表中。

我已经尝试了我的代码的两个版本。这是我的第一个版本。

int size = 10000;
int cont = 0;
        int n = 1;
        String[] arrstr2;
        int threadgroup = 10;
if (cont + threadgroup - 1 > size) {
                        arrstr2[i - cont] = subject.toString();
                    } else {
                        arrstr2[i - cont] = subject.toString();
                    }

                    if ((i == (threadgroup * n) - 1) || (i == size - 1)) {

                        cont = i + 1;
                        n = n + 1;
                        for (int j = 0; j < arrstr2.length; j++) {
                            Thread t = new Thread(new MyThread(arrstr2[j], l));
                            t.start();

                            try {
                                t.join();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        if (cont + threadgroup - 1 > size) {
                            arrstr2 = new String[size - i - 1];
                        }
                    }
                    i = i + 1;

在此版本中,我在总体执行方面没有获得优势。

这是我的第二个版本:

    int size = 10000;
    int cont = 0;
            int n = 1;
            String[] arrstr2;
            int threadgroup = 10;
    if (cont + threadgroup - 1 > size) {
                            arrstr2[i - cont] = subject.toString();
                        } else {
                            arrstr2[i - cont] = subject.toString();
                        }

                        if ((i == (threadgroup * n) - 1) || (i == size - 1)) {

                            cont = i + 1;
                            n = n + 1;
                            for (int j = 0; j < arrstr2.length; j++) {
                                Thread t = new Thread(new MyThread(arrstr2[j], l));
                                t.start();

                            }
try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            if (cont + threadgroup - 1 > size) {
                                arrstr2 = new String[size - i - 1];
                            }
                        }
                        i = i + 1;

在这种情况下我会丢失一些信息。 MyThread 是一个类,它执行一些处理并将结果放入列表 java:

public class MyThread implements Runnable{

    String subject;
    private List<String[]> l;

    public MyThread(String subject, List<String[]> l) {
        this.subject = subject;
        this.l = l;
    }

    @Override
    public void run() {

        synchronized (l){
        //do something
        String[] result = new String[2];
        result[0] = res0;
        result[1] = res1;
        l.add(result);
    }
}

对于我的目标来说,这段代码是正确的吗?如何在 Java 代码中启动一组线程并检索可接受的时间?

最佳答案

这是一个带有 ExecutorService 的小示例。线程大小固定为 10,但您可以根据需要进行调整。

StringTask 基本上反转给定的字符串。

public class Test {

    private static final int THREADS = 10;
    private static final int DATA_SIZE = 1000;

    public static void main(String[] args) {
        // Declare a new ExecutorService with a maximum of 2 threads.
        ExecutorService service = Executors.newFixedThreadPool(THREADS);

        // Prepare a list of Future results.
        List<Future<String>> futures = new ArrayList<Future<String>>(DATA_SIZE);

        // Submit the tasks and store the results.
        for (int i = 0; i < DATA_SIZE; i++) {
            futures.add(service.submit(new StringTask("Sample String " + i)));
        }

        // Accept no new tasks.
        service.shutdown();

        // Retrieve the actual String results.
        List<String> results = new ArrayList<String>(DATA_SIZE);
        try {
            for (Future<String> future : futures) {
                // The get() method blocks if the execution of the task is not finished.
                results.add(future.get());
                System.out.println(future.get());
            }
        } catch (ExecutionException ee) {
            System.out.println("Error while getting result!");
            ee.printStackTrace();
        } catch (InterruptedException ie) {
            System.out.println("Error while getting result!");
            ie.printStackTrace();
        }
    }

    /**
     * Callable task that reverses a given String.
     */
    private static final class StringTask implements Callable<String> {
        private String input;

        private StringTask(String input) {
            super();

            if (input == null) {
                throw new NullPointerException();
            }

            this.input = input;
        }

        @Override
        public String call() throws Exception {
            StringBuilder builder = new StringBuilder();

            for (int i = this.input.length() - 1; i >= 0; i--) {
                builder.append(this.input.charAt(i));
            }

            return builder.toString();
        }
    }
}

我在这里使用Callable而不是Runnable,因为Callable允许任务实际返回我们可以使用的结果(通过Future 界面)。如果您只需要执行一个任务,您可以简单地使用 Runnable!

关于java - 如何在Java代码中启动一组线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26120930/

相关文章:

java - 不明确的 Maven 依赖关系破坏了 Selenium

java - 如何接收 convertAndSend 发送的内容?

java - 如何在 LinearLayout 中并排设置 4 个编辑文本?

两秒后 Java GUI 变得马虎

winforms - C# Winforms : BeginInvoke still running on same thread?

multithreading - 一个条件变量,多个互斥体

java - 如何处理 Java FX2 中未捕获的运行时异常?

java - 类内部线程安全

android - RocksDB IO错误: lock db/LOCK: No locks available

c# - 无法从服务器线程更新 UI 中的文本框