ورود

View Full Version : سوال: نیاز به راهنمایی در مورد threadPool



[younes]
پنج شنبه 22 مرداد 1394, 11:15 صبح
اگر ممکنه لطفا در مورد ThreadPool با تعریف یک سناریو توضیح بدهید.
این تصویر متوجه نمیشم یعنی ما یه گروه مشخص مثلا ده ترد داریم بعد تسک هایی را به این گروه میدهیم تا همزمان انجام شوند و اگر این تسک ها بیشتر از ظرفیت pool بود در صف انتظار باقی میمانند.

134214

ahmad.mo74
شنبه 24 مرداد 1394, 09:54 صبح
این عکس خیلی خوب توضیح داده طرز کار thread pool ها رو.

سناریو کلی این هست که ما یه تعدادی ترد (ثابت یا متغیر با نیازمون) و یک صف داریم که داخل متد run اون ترد ها یه حلقه هست و به محض اینکه تسکی (مثلا Runnable) وارد صف شد، اون رو اجرا کنن و اطلاعات مربوط به اون رو مثل خروجیش، اررور هایی که داشته و ... رو بدن دست ما.

این نمونه کد دقیقا همون چیزی که تو عکس هست رو داره انجام میده :


import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;


/**
* @author ahmad
*/
public class ThreadPool {


private final Thread[] threads;
private final BlockingQueue taskQueue = new LinkedBlockingQueue<>();
private final AtomicBoolean shutdown = new AtomicBoolean(false);


public ThreadPool() {
this(Runtime.getRuntime().availableProcessors());
}


public ThreadPool(int poolSize) {
threads = new Thread[poolSize];
initPool();
}


private void initPool() {
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new TaskExecutor());
threads[i].start();
}
}


@SuppressWarnings("unchecked")
public CompletableFuture<Void> execute(Runnable task) {
CompletableFuture<Void> future = new CompletableFuture<>();
taskQueue.offer(new RunnableTask(task, future));
return future;
}


@SuppressWarnings("unchecked")
public <T> CompletableFuture<T> submit(Supplier<T> supplier) {
CompletableFuture<T> future = new CompletableFuture<>();
taskQueue.offer(new SupplierTask<>(supplier, future));
return future;
}


public void shutdown() {
if (shutdown.compareAndSet(false, true)) {
for (Thread t : threads) {
t.interrupt();
}
}
}


public boolean isShutdown() {
return shutdown.get();
}


private final class TaskExecutor implements Runnable {


@Override
@SuppressWarnings("unchecked")
public void run() {
while (!Thread.currentThread().isInterrupted() && !isShutdown()) {
try {
Object task = taskQueue.take();
if (task instanceof RunnableTask) {
Runnable t = ((RunnableTask) task).task;
CompletableFuture<Void> f = ((RunnableTask) task).future;
try {
t.run();
f.complete(null);
} catch (Throwable ex) {
f.completeExceptionally(ex);
}
} else if (task instanceof SupplierTask) {
Supplier s = ((SupplierTask) task).supplier;
CompletableFuture f = ((SupplierTask) task).future;
try {
f.complete(s.get());
} catch (Throwable ex) {
f.completeExceptionally(ex);
}
}
} catch (InterruptedException ignored) {
}
}
}


}


private final class RunnableTask {


private final Runnable task;
private final CompletableFuture<Void> future;


private RunnableTask(Runnable task, CompletableFuture<Void> future) {
this.task = task;
this.future = future;
}


}


private final class SupplierTask<T> {


private final Supplier<T> supplier;
private final CompletableFuture<T> future;


private SupplierTask(Supplier<T> supplier, CompletableFuture<T> future) {
this.supplier = supplier;
this.future = future;
}


}


}


کلاس CompletableFuture تو JDK 8 موجوده.

مثال :


import java.util.Date;


/**
* @author ahmad
*/
public class Test {


public static void main(String[] args) {


ThreadPool pool = new ThreadPool();


pool.execute(() -> System.out.println("Runnable task 1 !!!"))
.thenAccept(v -> System.out.println("Runnable task 1 completed."));


pool.execute(() -> {
System.out.println("Runnable task 2 !!!");
int i = 1 / 0;
}).thenAccept(v -> System.out.println("Runnable task 2 completed.")).exceptionally(ex -> {
System.out.println("Runnable task 2 completed exceptionally due to -> " + ex.getMessage());
return null;
});


pool.submit(() -> {
System.out.println("Supplier task!!!");
return System.currentTimeMillis();
}).thenAccept(when -> System.out.println("Supplier task completed on " + new Date(when) + "."));


pool.shutdown();


}


}


خروجی :


Runnable task 1 !!!
Runnable task 1 completed.
Runnable task 2 !!!
Runnable task 2 completed exceptionally due to -> java.lang.ArithmeticException: / by zero
Supplier task!!!
Supplier task completed on Sat Aug 15 10:40:42 IRDT 2015.