Programming

자바 : CPU 코어에 따라 스레드를 확장하는 방법은 무엇입니까?

procodes 2020. 8. 17. 10:40
반응형

자바 : CPU 코어에 따라 스레드를 확장하는 방법은 무엇입니까?


나는 좋은 자바 프로그래머는 아니고 취미 일 뿐이지 만 평범한 것보다 더 많은 것을 알고 싶어한다.

Java에서 여러 스레드로 수학적 문제를 해결하고 싶습니다. 내 수학 문제는 여러 스레드에서 풀고 싶은 작업 단위로 나눌 수 있습니다.

하지만 고정 된 양의 스레드가 작업하고 싶지는 않지만 대신 CPU 코어의 양에 코어 응답하는 스레드 양이 필요합니다. 제 문제는 인터넷에서 이것에 대한 쉬운 튜토리얼을 찾을 수 없다는 것입니다. 내가 찾은 것은 고정 스레드가있는 예입니다.

그래서 당신은 좋은 강의에 대한 링크로 저를 도울 수 있습니까? 아니면 저에게 쉽고 좋은 예를 줄 수 있습니까? 정말 좋네요 :)


정적 런타임 메소드 인 availableProcessors를 사용하여 Java Virtual Machine에서 사용 가능한 프로세스 수를 판별 할 수 있습니다 . 사용 가능한 프로세서 수를 결정했으면 해당 수의 스레드를 만들고 그에 따라 작업을 분할합니다.

업데이트 : 좀 더 명확히하기 위해 스레드는 Java의 객체 일 뿐이므로 다른 객체를 생성하는 것처럼 만들 수 있습니다. 따라서 위의 메서드를 호출하고 2 개의 프로세서를 반환한다고 가정 해 보겠습니다. 대박. 이제 새 스레드를 생성하고 해당 스레드에 대한 작업을 분할하고 스레드를 시작하는 루프를 만들 수 있습니다. 내가 의미하는 바를 보여주는 몇 가지 의사 코드는 다음과 같습니다.

int processors = Runtime.getRuntime().availableProcessors();
for(int i=0; i < processors; i++) {
  Thread yourThread = new AThreadYouCreated();
  // You may need to pass in parameters depending on what work you are doing and how you setup your thread.
  yourThread.start();
}

자신 만의 스레드를 만드는 방법에 대한 자세한 내용은 이 튜토리얼을 참조하십시오 . 또한 스레드 생성을 위해 스레드 풀링 을 살펴볼 수도 있습니다 .


이 항목에 대한 java.util.concurrent 프레임 워크도 살펴보고 싶을 것입니다. 다음과 같은 것 :

ExecutorService e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// Do work using something like either
e.execute(new Runnable() {
        public void run() {
            // do one task
        }
    });

또는

    Future<String> future = pool.submit(new Callable<String>() {
        public String call() throws Exception {
            return null;
        }
    });
    future.get();  // Will block till result available

이것은 자신의 스레드 풀 등에 대처하는 것보다 훨씬 좋습니다.


Doug Lea (동시 패키지 작성자)는 관련이있을 수있는이 문서를 보유하고 있습니다. http://gee.cs.oswego.edu/dl/papers/fj.pdf

Fork Join 프레임 워크가 Java SE 7에 추가되었습니다. 다음은 몇 가지 추가 참조입니다.

http://www.ibm.com/developerworks/java/library/j-jtp11137/index.html 기사 : Brian Goetz

http://www.oracle.com/technetwork/articles/java/fork-join-422606.html


옵션 1:

newWorkStealingPool fromExecutors

public static ExecutorService newWorkStealingPool()

사용 가능한 모든 프로세서를 대상 병렬 처리 수준으로 사용하여 작업 도용 스레드 풀을 만듭니다.

이 API를 사용하면 .NET Core에 코어 수를 전달할 필요가 없습니다 ExecutorService.

grepcode 에서이 API 구현

/**
     * Creates a work-stealing thread pool using all
     * {@link Runtime#availableProcessors available processors}
     * as its target parallelism level.
     * @return the newly created thread pool
     * @see #newWorkStealingPool(int)
     * @since 1.8
     */
    public static ExecutorService newWorkStealingPool() {
        return new ForkJoinPool
            (Runtime.getRuntime().availableProcessors(),
             ForkJoinPool.defaultForkJoinWorkerThreadFactory,
             null, true);
    }

옵션 2 :

Executors또는 에서 newFixedThreadPool API other newXXX constructors를 반환합니다.ExecutorService

public static ExecutorService newFixedThreadPool(int nThreads)

nThreads를 Runtime.getRuntime().availableProcessors()

옵션 3 :

ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                      int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue)

Runtime.getRuntime().availableProcessors()매개 변수로 전달 합니다 maximumPoolSize.


표준 방법은 Runtime.getRuntime (). availableProcessors () 메소드입니다. 대부분의 표준 CPU에서는 여기에 최적의 스레드 수 (실제 CPU 코어 수가 아님)를 반환합니다. 그러므로 이것은 당신이 찾고있는 것입니다.

예:

ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

다음과 같이 실행기 서비스를 종료하는 것을 잊지 마십시오 (그렇지 않으면 프로그램이 종료되지 않습니다).

service.shutdown();

Here just a quick outline how to set up a future based MT code (offtopic, for illustration):

CompletionService<YourCallableImplementor> completionService = 
    new ExecutorCompletionService<YourCallableImplementor>(service);
    ArrayList<Future<YourCallableImplementor>> futures = new ArrayList<Future<YourCallableImplementor>>();
    for (String computeMe : elementsToCompute) {
        futures.add(completionService.submit(new YourCallableImplementor(computeMe)));
    }

Then you need to keep track on how many results you expect and retrieve them like this:

try {
  int received = 0;
  while (received < elementsToCompute.size()) {
     Future<YourCallableImplementor> resultFuture = completionService.take(); 
     YourCallableImplementor result = resultFuture.get();
     received++; 
  }
} finally {
  service.shutdown();
}

On the Runtime class, there is a method called availableProcessors(). You can use that to figure out how many CPUs you have. Since your program is CPU bound, you would probably want to have (at most) one thread per available CPU.

참고URL : https://stackoverflow.com/questions/1980832/java-how-to-scale-threads-according-to-cpu-cores

반응형

'Programming' 카테고리의 다른 글

긴 정수의 최대 값  (0) 2020.08.17
Windows에서 MySQL과 Python 통합  (0) 2020.08.17
* 문자 *로 너비 지정  (0) 2020.08.17
Spring RestTemplate 시간 초과  (0) 2020.08.15
SOAP 메시지와 WSDL의 차이점은 무엇입니까?  (0) 2020.08.15