class DirectExecutor implements Executor { public void execute(Runnable r) { r.run(); } }
class ThreadPerTaskExecutor implements Executor { public void execute(Runnable r) { new Thread(r).start(); } }ThreadPerTaskExecutor her execute edildiğinde yeni bir thread açmaktadır.
class SerialExecutor implements Executor { final Queue tasks = new ArrayDeque(); final Executor executor; Runnable active; SerialExecutor(Executor executor) { this.executor = executor; } public synchronized void execute(final Runnable r) { tasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (active == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((active = tasks.poll()) != null) { executor.execute(active); } } }
import static java.util.concurrent.TimeUnit.SECONDS; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; public class Greeting { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public void forAnHour() { final Runnable greeter = new Runnable() { public void run() { System.out.println("merhaba"); } }; //10 snde bir merhaba yazacak final ScheduledFuture<?> greeterHandle = scheduler.scheduleAtFixedRate(greeter, 10, 10, SECONDS); // bir saat sonra sona erdirilecek scheduler.schedule(new Runnable() { public void run() { greeterHandle.cancel(true); } }, 60 * 60, SECONDS); } public static void main(String[] args) { Greeting greeting=new Greeting(); greeting.forAnHour(); } }Öncelikle greeter adında erkana merhaba yazan bir Runnable yaratıyoruz. scheduleAtFixedRate ile 10 sn'de bir bu Runnable çalıştırılacak şekilde ayarlanmıştır. schedule() yöntemi ile de 1 saat sonra bir task çalışacak ve 10 sn bir çalışan greeterHandle durdurulacaktır. Uygulama çalıştığında 10 sn'de bir merhaba yazısı çıktıda görülecektir:
merhaba merhaba merhaba merhaba merhaba merhaba
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class NetworkService implements Runnable { private final ServerSocket serverSocket; private final ExecutorSevrvice pool; public NetworkService(int port, int poolSize) throws IOException { serverSocket = new ServerSocket(port); pool = Executors.newFixedThreadPool(poolSize); } public void run() { // run the service try { for (;;) { pool.execute(new Handler(serverSocket.accept())); } } catch (IOException ex) { pool.shutdown(); } } public static class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() { System.out.println("socket handler run..."); } } public static void main(String[] args) throws IOException { NetworkService networkService=new NetworkService(8081, 10); System.out.println("Network service running"); networkService.run(); } }NetworkService sınıfınun run yöntemi main'deki gibi çağrıldığında serverSocket.accept() ile yeni bir socket beklenir duruma geçilecektir. 8081 portunu dinlenilmektedir. En fazla 10 thread olacak şekilde bir havuz yaratılmıştır. Bir socket açılırsa Handler'daki kod çalıştırılır ve yeni bir socket beklenir. Test edebilmek için socket açan bir client örneği yapalım:
import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; public class NetworkServiceClient { public static void main(String[] args) throws UnknownHostException, IOException { for (int i=0;i<10;i++) { Socket socket=new Socket("10.26.12.162", 8081); } } }Döngü açıp 10 tane socket açıyoruz. Her socket'te sunucu tarafında Handler çalıştırılır ve ekrana socket hander run... yazısını yazar:
Network service running socket handler run... socket handler run... socket handler run... socket handler run... socket handler run... socket handler run... socket handler run... socket handler run... socket handler run... socket handler run...Eğer 10 thread çalışırken yeni thread'lar eklenirse, önce elindeki 10 thread'i bitirir ve diğer 10 thread'e devam eder. Bu şekilde tüm thread'leri çalıştırır. Bunu anlamak için run yöntemini aşağıdaki çalıştırıp, Thread'leri bekletebiliriz:
public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("socket hander run..."); }Bu şekilde döngüyü 100'e çekip çalıştırırsak, 10'ar 10'ar mesajların yazılacağını görebilirsiniz.
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestApp { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(10); for (int i = 0; i < 25; i++) { Runnable worker = new MyRunnable(i+1); executor.execute(worker); } executor.shutdown(); // Thread'lerin sona ermesi beklenir while (!executor.isTerminated()) { } System.out.println("Uygulama sona erdi"); } public static class MyRunnable implements Runnable { private int index=0; public MyRunnable(int index) { this.index=index; } @Override public void run() { System.out.println(index+".nci thread calisiyor"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }Uygulama önce 10 thread havuzu olan bir ExecutorService servisi yaratılıyor. Havuzun anlamı aynı anda en fazla 10 Thread'in çalışmasıdır. Sonra 25 Thread yaratıp çalıştırıryoruz. Ardından shutdown() ile kapatıyoruz. Ancak executor.isTerminated() ile tüm Thread'lerin çalışmasını tamamlamasını bekliyoruz. Uygulama çalıştığı zaman 25 Thread'i 10ar 10ar işleyecek ve kapanacaktır :
2.nci thread calisiyor 3.nci thread calisiyor 1.nci thread calisiyor 4.nci thread calisiyor 5.nci thread calisiyor 6.nci thread calisiyor 7.nci thread calisiyor 8.nci thread calisiyor 9.nci thread calisiyor 10.nci thread calisiyor 11.nci thread calisiyor 13.nci thread calisiyor 12.nci thread calisiyor 14.nci thread calisiyor 15.nci thread calisiyor 16.nci thread calisiyor 17.nci thread calisiyor 19.nci thread calisiyor 18.nci thread calisiyor 20.nci thread calisiyor 21.nci thread calisiyor 23.nci thread calisiyor 22.nci thread calisiyor 25.nci thread calisiyor 24.nci thread calisiyor Uygulama sona erdi
import java.util.concurrent.*; public class Test { public static void main(String[] args) { ExecutorService executorService=Executors.newSingleThreadExecutor(); Future<String> future = executorService.submit( new Callable<String>() { public String call() { return "OK"; } } ); try { System.out.println(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } executorService.shutdown(); } }İlk işlem olarak tel Thread'li bir ExecutorService yaratıyoruz. Ona çalıştırmak için bir Callable veriyoruz. Yaratılan Callable sadece String sonucu döndürüyor. ExecutorService'in submit() yöntemi geriye Future döndürüyor. Daha sonra get() yonteminde ana Thread sonucu bekler. Sonuç geldiğinde ise sonuç ekrana basılır. Son satırla da ExecutorService shotdown edilir. aksi takdirde uygulama sürekli ayakta kalırdı.