Я хотел бы знать, если есть какая-то разница между этими двумя подходами выполнения задачи с использованием многопоточности в Java 7:, какой подход будет лучше - многопоточность примера
Краткого требования - Я должен обрабатывать 200 записей, одновременно, и каждая запись должна обрабатываться только один раз.
Подход 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, взятое в примере кода, будет в миллиардах в реальном сценарии. Пожалуйста, предложите, какой из них будет лучше с точки зрения памяти и процессора и т. Д.
Спасибо.
Редактировать - добавить подход 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 - миллиарды - большой прыжок. Слишком большое для нас, чтобы прокомментировать, imo. Вы должны быть более конкретными. В частности, «миллиарды» потоков не могут выполняться в отдельных системах, поэтому вам, вероятно, придется подумать о том, как распределить вашу проблему по нескольким системам. Это намного больше, чем StackOverflow был разработан для ответа. – markspace
Нет, не миллиарды нитей, миллиарды записей (в 10-15 потоках). –
Ооо, ну, честно говоря, я все еще не могу сказать. Мне нужно знать, что на самом деле делает ваша «задача», и немного больше об аппаратном обеспечении. Как правило, ExecutorService предпочитает создавать свои собственные потоки, если это то, о чем вы просите. – markspace