2012-08-30 6 views
8

자바의 스레드에 관한 많은 자습서를 공부했지만 저의 답을 찾을 수 없습니다.스레드를 사용하여 두 개의 독립적 인 작업을 동시에 수행합니다.

내 질문은 : 두 개의 독립적 인 스레드를 동시에 실행하는 방법은 무엇입니까?

내 경우 : 두 가지 작업이 있습니다.

  1. 는 모바일 기기에 푸시 알림을 보내 데이터베이스
  2. 에 일부 데이터를 저장합니다.

이 두 작업은 독립적이므로 동시에 실행하려고합니다.

두 스레드가있는 스레드 풀을 사용해 보았지만 데이터베이스 작업이 빨리 완료되지만 푸시 알림을 보내는 데 시간이 걸리는 것이 문제였습니다.

따라서 하나의 작업이 완료되어 다른 작업이 보류중인 경우 예외가 발생합니다.

또한 스레드를 사용하지 않고도 정상적으로 실행되므로 내 코드에는 아무런 문제가 없습니다. 나는 개인적으로 ExecutorService의 사용을 선호하는 것

+2

는 *은 예외 * 여기에 예외를 게시 할 수 유용 할 수 있습니다 발생 – Robin

+1

어쨌든에서 관련 작업이 있습니까? 데이터가 저장된 후에 알림을 보내시겠습니까 ?? 아니면 그냥 대기열에 무작위 작업을 잔뜩 대기열에두고 싶니 ??? – MadProgrammer

+0

@MadProgrammer 귀하의 빠른 회신에 감사드립니다.데이터베이스 두 작업은 서로 독립적입니다. 데이터가 먼저 저장되거나 푸시 알림이 먼저 전송되는지 여부는 중요하지 않습니다. –

답변

25
new Thread(new Runnable() { 
    public void run() { 
     System.out.println("Look ma, no hands"); 
    } 
}).start(); 

new Thread(new Runnable() { 
    public void run() { 
     System.out.println("Look at me, look at me..."); 
    } 
}).start(); 

가 잘 작동 사전에

감사합니다 ....

는 기본적으로 간단한 작업의 몇 가지를 실행하는 ExecutorService을 사용하여 ...

그래서 나는이 정말 간단한 예를 쓴 ExecutorService를 예 업데이트되었습니다. 약자로, 두 작업은

지금 ExecutorService service = Executors.newFixedThreadPool(1);ExecutorService service = Executors.newFixedThreadPool(2); 변경 ... 서로 (동시) 병렬로

public static void main(String[] args) throws InterruptedException { 
    ExecutorService service = Executors.newFixedThreadPool(2); 
    service.submit(new PathScanner()); 
    service.submit(new Counter()); 

    service.shutdown(); 
    service.awaitTermination(1, TimeUnit.DAYS); 

    System.exit(0); 
} 

public static class PathScanner implements Callable<Object> { 

    @Override 
    public Object call() throws Exception { 
     scan(new File("C:/"), 0); 
     return null; 
    } 

    protected void scan(File path, int deepth) { 
     if (deepth < 15) { 
      System.out.println("Scanning " + path + " at a deepth of " + deepth); 

      File[] files = path.listFiles(); 
      for (File file : files) { 
       if (file.isDirectory()) { 
        scan(file, ++deepth); 
       } 
      } 
     } 
    } 
} 

public static class Counter implements Callable<Object> { 

    @Override 
    public Object call() throws Exception { 
     for (int index = 0; index < 1000; index++) { 
      Thread.sleep(1); 
      System.out.println(index); 
     } 
     return null; 
    } 
} 

실행을 실행하고 다시 실행됩니다. 그 차이를 보았 니?

executor가 큐를 처리하는 동안 사용할 수있는 동시 스레드의 수를 제어하는 ​​방법입니다.

더 많은 작업을 만들어 대기열에 추가하고 얻은 것을 확인하십시오.

+2

+1 빠른 예를 들어 ... – John

+0

빠른 응답과 예제에 감사드립니다! 대답은 받아 들였다! :-) –

+0

첫 번째 예에서는 스레드의 ID를 어떻게 인쇄합니까? –

0

멀티 스레딩을 사용하여 여러 폴더에서 파일을 검색하는 유스 케이스가있었습니다. 입력으로 나는 루트 디렉토리 경로 만 갖고 있었고 몇 개의 하위 디렉토리가있을 수 있습니다. 가정 - 파일은 항상 하위 디렉터리 중 하나에서만 사용할 수 있습니다.

import java.io.File; 
import java.io.FileFilter; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class SearchFile implements Runnable { 

    private String dirPath = null; 

    public SearchFile() { 

    } 

    public SearchFile(String dirPath) { 
     this.dirPath = dirPath; 
    } 

    public static void main(String[] args) { 
     long startTime = System.currentTimeMillis(); 
     File dir = new File("D://"); 
     checkRootDirectory(dir); 
     long endTime = System.currentTimeMillis(); 
     System.out.println("Time taken: "+(endTime - startTime) + "ms"); 
    } 

    private static void checkRootDirectory(File root) { 
     File[] list = root.listFiles(new FileFilter() { 

      @Override 
      public boolean accept(File pathname) { 
       return pathname.isDirectory() && !pathname.isHidden(); 
      } 
     }); 

     ExecutorService service = Executors.newFixedThreadPool(list.length); 
     for (File directories : list) { 
      String dirPath = directories.getAbsolutePath(); 
      Thread thread = new Thread(new SearchFile(dirPath)); 
      service.execute(thread); 
     } 
     service.shutdown(); 
     while(!service.isTerminated()) { 

     } 
    } 

    @Override 
    public void run() { 
     checkEachDirectory(new File(dirPath), "Temp.txt"); 
    } 

    private void checkEachDirectory(File root, String fileName) { 
     File[] list = root.listFiles(); 
     if (null != list) { 
      for (File dir : list) { 
       if (dir.isDirectory()) { 
        checkEachDirectory(dir, fileName); 
       } else if (fileName.equalsIgnoreCase(dir.getName())) { 
        System.out.println(
          "Thread name: " + Thread.currentThread().getName() + " Founded @" + dir.getAbsolutePath()); 
       } 
      } 
     } 
    } 
} 
관련 문제