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
이것은 자신의 스레드 풀 등에 대처하는 것보다 훨씬 좋습니다.
답변
옵션 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 :
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
에 Runtime.getRuntime().availableProcessors()
매개 변수로 전달 합니다 maximumPoolSize
.
답변
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
기사 by Brian Goetz
http://www.oracle.com/technetwork/articles/java/fork-join-422606.html
답변
표준 방법은 Runtime.getRuntime (). availableProcessors () 메소드입니다. 대부분의 표준 CPU에서는 여기에 최적의 스레드 수 (실제 CPU 코어 수가 아님)를 반환합니다. 그러므로 이것은 당신이 찾고있는 것입니다.
예:
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
다음과 같이 실행기 서비스를 종료하는 것을 잊지 마십시오 (그렇지 않으면 프로그램이 종료되지 않습니다).
service.shutdown();
다음은 미래 기반 MT 코드를 설정하는 방법에 대한 간략한 개요입니다 (설명을 위해 주제를 벗어남).
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)));
}
그런 다음 예상되는 결과 수를 추적하고 다음과 같이 검색해야합니다.
try {
int received = 0;
while (received < elementsToCompute.size()) {
Future<YourCallableImplementor> resultFuture = completionService.take();
YourCallableImplementor result = resultFuture.get();
received++;
}
} finally {
service.shutdown();
}
답변
Runtime 클래스에는 availableProcessors ()라는 메서드가 있습니다. 이를 사용하여 보유한 CPU 수를 파악할 수 있습니다. 프로그램이 CPU 바운드이기 때문에 사용 가능한 CPU 당 하나의 스레드를 갖고 싶을 것입니다.