멀티 스레딩 동시에 200 개의 레코드가 있어야하며 각 레코드는 한 번만 처리해야합니다.는 더 나은 방법이 될 나는 자바 7에 멀티 스레딩을 사용하여 작업을 수행하는 이러한 두 가지 접근 방식의 차이가 있는지 알고 싶습니다 예를
접근 1 :
public class Counter {
private static int count = -1;
private static final Object lock = new Object();
public static int getCount() {
synchronized (lock) {
return ++count;
}
}
}
public class Task implements Runnable {
@Override
public void run() {
int count = 0;
while((count = Counter.getCount()) < 200) {
System.out.println(Thread.currentThread().getName() + " " + count);
// process record # count
}
}
}
public class Tester {
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
service.execute(new Task());
}
service.shutdown();
service.awaitTermination(5, TimeUnit.MINUTES);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
접근법 2 : 둘 다 잘 실행과 같은 출력을 생성 거의 같은 시간이 소요
public class Task2 implements Runnable {
private int i = 0;
public Task2(int i) {
super();
this.i = i;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + i);
// process record # i
}
}
public class Tester2 {
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 200; i++) {
service.execute(new Task2(i));
}
service.shutdown();
service.awaitTermination(5, TimeUnit.MINUTES);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
. 그러나 예제 코드에서 취한 200 개의 숫자는 실제 시나리오에서 수십억입니다. 어느 것이 메모리 및 CPU 등의면에서 더 좋을지 제안하십시오.
감사합니다.
편집 - 지미 T.의 제안에 따라 접근 방식 3 추가.
접근법 3 :
public class Tester3 {
public static void main(String[] args) throws InterruptedException {
int processedRecords = 0;
int totalRecords = 200;
int recordsPerThread = 10;
boolean continueProcess = true;
ExecutorService service = Executors.newFixedThreadPool(10);
while(continueProcess) {
int startIndex = processedRecords;
int endIndex = startIndex + recordsPerThread - 1;
if (endIndex >= totalRecords - 1) {
endIndex = totalRecords - 1;
continueProcess = false;
}
processedRecords = processedRecords + recordsPerThread;
service.submit(new Task3(startIndex, endIndex));
}
service.shutdown();
service.awaitTermination(5, TimeUnit.MINUTES);
}
}
public class Task3 implements Runnable {
private int startIndex = 0;
private int endIndex = 0;
public Task3(int startIndex, int endIndex) {
super();
this.startIndex = startIndex;
this.endIndex = endIndex;
}
@Override
public void run() {
System.out.println("processing records from " + startIndex + " to " + endIndex);
}
}
200 억은 큰 도약입니다. 우리가 의견을 말하기에는 너무 큽니다. 좀 더 구체적이어야합니다. 특히 수십억 개의 스레드를 단일 시스템에서 실행할 수 없으므로 여러 시스템에 문제를 분산시키는 방법을 생각해야 할 것입니다. StackOverflow가 대답하도록 고안된 것 이상으로 좋습니다. – markspace
수십억 개의 스레드가 아니라 수십억 개의 레코드 (10-15 스레드). –
우우, 솔직히 나는 아직도 말할 수 없다. 당신의 "작업"이 실제로하는 일과 하드웨어에 대해서 좀 더 알아야합니다. 일반적으로 ExecutorService가 자신의 스레드를 만드는 것보다 선호됩니다. – markspace