亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

帶有打開文件的 Java 多線程

帶有打開文件的 Java 多線程

飲歌長嘯 2021-12-22 20:14:49
我有一個 txt 文件:order_me.txt,其中有一些整數需要使用 4 個線程進行排序。他們需要同時工作,但不能做同樣的事情。我已經設法對整數進行排序,但有些東西不正常......這是線程類:public class Threading {    static List<Integer> integersCopy = new ArrayList<>();    public static void main(String[] args) {        openFile();        Thread t1 = new Thread(new Command("thread 1", integersCopy));        t1.start();        Thread t2 = new Thread(new Command("thread 2", integersCopy));        t2.start();        Thread t3 = new Thread(new Command("thread 3", integersCopy));        t3.start();        Thread t4 = new Thread(new Command("thread 4", integersCopy));        t4.start();        try {            if (t1.isAlive())                t1.join();            if (t2.isAlive())                t2.join();            if (t3.isAlive())                t3.join();            if (t4.isAlive())                t4.join();        } catch (Exception e) {            System.out.println("Exception with threads");        }    }    public static void openFile() {        File file = new File("order_me.txt");        try {            Scanner scanner = new Scanner(file);            List<Integer> integers = new ArrayList<>();            while (scanner.hasNext()) {                if (scanner.hasNextInt()) {                    integers.add(scanner.nextInt());                } else {                    scanner.next();                }            }            integersCopy = integers;            System.out.println("File opened successfully");        } catch (Exception e) {            System.out.println("Triggered exception");        }    }這是排序類:    import java.util.Collections;    import java.util.List;    public class Command implements Runnable {    String threadName;    List<Integer> listOfInts;    Command(String name, List<Integer> list) {        threadName = name;        listOfInts = list;    }        }    }}
查看完整描述

2 回答

?
素胚勾勒不出你

TA貢獻1827條經驗 獲得超9個贊

一旦一個線程對整數進行了排序,嘗試在多個線程中做同樣的事情就沒有意義了,事實上,因為這不是以線程安全的方式完成的,你很可能會破壞列表。

簡而言之,使用一個線程。


查看完整回答
反對 回復 2021-12-22
?
喵喔喔

TA貢獻1735條經驗 獲得超5個贊

您正在改變List多個線程上的共享。ArrayList不是線程安全的:您需要使用線程安全Collection或使用Collections.synchronizedList.

如果您在每個線程中對相同的列表進行排序,那么您的實現可能是錯誤的:

  • 您應該在父線程中閱讀一次列表

  • 您應該按線程數拆分列表,并對每個自己的線程中的每個子列表進行排序。這就是Thread在這種情況下的目的:分工去做。

  • 然后您應該在父線程中加入子列表:在加入過程中,您將不得不進行排序。由于每個子列表都已排序,因此您可以使用更快的排序(例如:如果子列表 A 的第一個項目在子列表 B 的最后一個之后,那么您可以將 A 的所有項目添加到 B 中)或標準排序。

此外,您可能Stream會這樣做:

  • parallel()方法是Stream使用多個線程的原因。

  • ForkJoinPool用于使用另一個線程池(請參閱此 SO 答案)。舉個例子可能沒用。

  • 遺憾的是,Scanner不能轉換為IntStreamStream。您需要使用Files.lines和 aPattern用空格 ( \s+)分割行。

  • 我們使用flatMapToInt要轉換為IntStreamOptionalInt(這將是空的無效數字,例如:*a4)。

  • sorted()確保我們使用默認排序進行排序。使用比較器進行排序需要一個普通的 Stream,因此,將flatMapToInt其更改為flatMap.

  • toArray()在這種情況下可能比在第二個示例中使用ArrayListof更好Integer

使用 Java 11 測試的代碼:

  public static void main(final String[] args) throws Exception {

    final Pattern splitter = Pattern.compile("\\s+");

    // see

    // 

    final ForkJoinPool forkJoinPool = new ForkJoinPool();

    final Future<int[]> future = forkJoinPool.submit(() -> {

      try (final Stream<String> lines = Files.lines(Paths.get("myfile.txt"), StandardCharsets.UTF_8)) {

        return lines.parallel() // use default parallel ExecutorService

            .flatMap(splitter::splitAsStream) // tokenize input

            .flatMapToInt(s -> parseInt(s).stream()) // convert to number (eg: nextInt())

            .sorted().toArray();

      }

    });


    final int[] result = future.get();

    System.out.println("result.length: " + result.length);

    // Arrays.stream(result).forEach(System.out::println);

    final Future<List<Integer>> future2 = forkJoinPool.submit(() -> {

      try (Stream<String> lines = Files.lines(Paths.get("myfile.txt"), StandardCharsets.UTF_8)) {

        return lines.parallel() // use default parallel ExecutorService

            .flatMap(splitter::splitAsStream) // tokenize input

            .flatMapToInt(s -> parseInt(s).stream()) // convert to number (eg: nextInt())

            .sorted().collect(ArrayList::new, List::add, List::addAll) // probably best to use

                                                                       // array.

        ;

      }

    });

    final List<Integer> result2 = future2.get();

    System.out.println("result2.length: " + result2.size());

  }


  static OptionalInt parseInt(final String s) {

    try {

      return OptionalInt.of(Integer.parseInt(s));

    } catch (final NumberFormatException e) {

      return OptionalInt.empty();

    }

  }


查看完整回答
反對 回復 2021-12-22
  • 2 回答
  • 0 關注
  • 170 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號