2017-11-01 3 views
-1

使用するデータ構造は何ですか?1つのスレッドが書き込みを行い、複数の読み取り/削除を実行する場合の最適なデータ構造は何ですか?

考える:ファイル

  • 再帰的にトラバースし、データ構造に 各ファイルの完全なパスを追加し、単一スレッドの

    1. 百万。
    2. 「N」スレッド
    3. A)1つのエントリを読み込むB)同じエントリを削除するC)数秒かかるエントリを処理するD)次の利用可能なエントリに移動する(他のすべてと競合する次のエントリのスレッド)
    4. オーダーが重要かもしれません。審査員はまだ出ている。
    5. 指定されたエントリは一度だけ処理する必要があります。

    Java 8または9のどのデータ構造が最適でしょうか?

  • +5

    私の待ち行列のような音。おそらくhttps://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html – Blorgbeard

    +0

    また、コメントを投稿する代わりに質問を編集することもできます。 – Blorgbeard

    +0

    これはパターンプロデューサ - コンシューマ –

    答えて

    0

    実際、スレッドを保持しブロックするExecutorService機能を利用する方法でこれを行うことができます。ジャージーとJava 8の機能を使用する:一度にスレッドの固定数を実行しながら

    public static void main(String[] args) throws IOException { 
    
        dirSource = Paths.get("C:\\path\\toLoad"); 
        dirDestination = Paths.get("C:\\path\\loaded"); 
    
        // This is a blocking pool. If there are more attempts to submit 
        // (which there will be) requests for execution than there are 
        // available threads, they will block until one becomes free. 
        ExecutorService executorService = Executors.newFixedThreadPool(40); 
    
        AddFilesToQueue aftq = new AddFilesToQueue(executorService, dirSource, dirDestination); 
    
        Files.walkFileTree(dirSource, aftq); 
    
        //System.exit(0); 
    } 
    
    public class AddFilesToQueue extends SimpleFileVisitor<Path> { 
    
        ExecutorService es; 
        Path myDirSource; 
        Path myDirDestination; 
    
        public AddFilesToQueue(ExecutorService es, Path dirSource, Path dirDestination) { 
         super(); 
         this.es = es; 
         this.myDirSource = dirSource; 
         this.myDirDestination = dirDestination; 
        } 
    
        public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attr) { 
    
         if (attr.isRegularFile()) { 
          es.submit(new MyRunnable(sourceFile, myDirSource, myDirDestination)); 
         } 
         return FileVisitResult.CONTINUE; 
        } 
    
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) { 
         return FileVisitResult.CONTINUE; 
        } 
    } 
    
    public class MyRunnable implements Runnable { 
    
        Path mySourceFile; 
        Path mySourceDirectory; 
        Path myDestDirectory; 
        Path fullDestination; 
    
        public MyRunnable(Path sourceFile, Path sourceDirectory, Path destinationDirectory) { 
         this.mySourceFile = sourceFile; 
         this.mySourceDirectory = sourceDirectory; 
         this.myDestDirectory = destinationDirectory; 
         int nameCount = mySourceDirectory.getNameCount(); 
         Path subPath = this.mySourceFile.subpath(nameCount, mySourceFile.getNameCount()); 
         this.fullDestination = Paths.get(destinationDirectory.toString(), subPath.toString()); 
        } 
    
        @Override 
        public void run() { 
         Client client = ClientBuilder.newClient(); 
         WebTarget webTarget = client.target("http://192.168.1.142:8080/abc/myworkflow/process/load/1?forcesync=true"); 
         webTarget.property("Content-Type", "application/xml"); 
         Invocation.Builder ib = webTarget.request(MediaType.APPLICATION_XML); 
         String content = ""; 
         try { 
          content = new String (Files.readAllBytes(mySourceFile)); 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
         Response response = ib.post(Entity.entity(content, MediaType.APPLICATION_XML)); 
         if (response.getStatus() == 200) { 
          try { 
           Files.move(mySourceFile, fullDestination); 
          } catch (IOException e) { 
           e.printStackTrace(); 
          } 
         } 
        } 
    } 
    

    上記のことは、xmlファイルの何百万人を読んで、スレッドのプールに追加されます。

    実行待ちのスタックされたスレッドが何百万もある場合、executorserviceに問題があると思われます。メモリが不足していますか?これが起こると、プロデューサのコンシューマブロックキューが使用されます。

    +0

    私がまだ取り組んでいる唯一の部分は、すべての作業が終了したら正常に終了する方法です。 –

    関連する問題