public class Post implements Activity {
	private Date tarih;
	public Post(Date tarih)
	{
		this.tarih= tarih;
	}

	@Override public Date getCreatedAt()
	{
		return tarih;
	}

	@Override public String toString()
	{
		return "Post{"
			+ "tarih=" + tarih+ '}';
	}
}

Çoklu iş parçacığı oluşturma, CPU’nun maksimum kullanımı için bir programın iki veya daha fazla bölümünün eşzamanlı olarak yürütülmesini sağlayan bir Java özelliğidir. Böyle bir programın her bölümüne iş parçacığı denir. Bu nedenle, iş parçacıkları bir süreç içindeki hafif süreçlerdir.

Runnable
Örneklerinin bir iş parçacığı tarafından yürütülmesi amaçlanan herhangi bir sınıf, Runnable arabirimini uygulamalıdır. Sınıf, bağımsız değişken içermeyen bir çalıştırma yöntemi tanımlamalıdır. Bu arabirim, etkinken kod çalıştırmak isteyen nesneler için standart bir protokol sağlamak üzere tasarlanmıştır. Örneğin iş parçacığı, Runnable arabirimini uygular. Aktif olmak, yalnızca bir iş parçacığının başladığı ve henüz sonlandırılmadığı anlamına gelir. Ayrıca, Runnable, Thread’i alt sınıflandırmazken bir sınıfın etkin olmasına izin verir. Runnable’ı uygulayan bir sınıf, bir Thread örneği oluşturup kendisini hedef olarak geçirerek Thread’i alt sınıflandırmadan kod yürütebilir.

Runnable ile yeni bir iş parçacığı oluşturmak için şu adımları izleyin:

  1. Bir Runnable uygulayıcısı oluşturun ve run() yöntemini çağırın.
  2. Bir Thread örneği oluşturun ve uygulayıcıyı bu örneğe geçirin. İş parçacığı, Runnable örneklerini kabul eden bir Object() { [yerel kod] } işlevine sahiptir.
  3. Thread örneğinde start() öğesini çağırın; Başlat, uygulayıcının run() öğesini dahili olarak çağırır. start() öğesinin çağrılması, run () öğesinde belirtilen kodu yürüten yeni bir İş Parçacığı oluşturur.
public class Comment implements Activity {
	private Date tarih;
	public Comment(Date tarih)
	{
		this.tarih= tarih;
	}
	@Override public Date getCoursesAddedAt()
	{
		return tarih;
	}
	@Override public String toString()
	{
		return "Comment{"
			+ "tarih=" + tarih+ '}';
	}
}
public class GfG implements Activity {

	private Date tarih;

	public GfG(Date tarih)
	{
		this.tarih= tarih;
	}

	@Override public Date getCoursesAddedAt()
	{
		return tarih;
	}

	@Override public String toString()
	{
		return "GfG{"
			+ "tarih=" + tarih+ '}';
	}
}

Callable
Sonuç üreten ve özel durum oluşturma yeteneğine sahip bir görev. Uygulayıcılar, bağımsız değişken almayan çağrı adı verilen tek bir yöntem tanımlar. Çağrılabilir arabirim, her ikisinin de örnekleri başka bir iş parçacığı tarafından yürütülebilecek sınıflar için tasarlanmış olması bakımından Runnable arabirimine benzer. Öte yandan, Runnable bir değer döndürmez ve denetlenen bir özel durum atamaz. Yürütücüler, diğer yaygın formlardan Callable sınıflarına dönüştürmek için yardımcı program yöntemleri içerir. Bir Runnable’ı uygulamak için, hiçbir şey döndürmeyen run() yönteminin uygulanması gerekirken, bir Callable’ın uygulanması için call() yönteminin uygulanması gerekir ve bu yöntem tamamlandığında bir sonuç döndürür. Bir iş parçacığının Callable ile oluşturulamayacağına dikkat etmek önemlidir; yalnızca bir Runnable bunu yapabilir. Diğer bir ayrım, call() yönteminin bir özel durum atabilmesi, run() yönteminin ise atamamasıdır.

public class Like implements Activity {
	private Date tarih;

	public Like(Date tarih)
	{
		this.tarih= tarih;
	}

	@Override public Date getCreatedAt()
	{
		return tarih;
	}

	@Override public String toString()
	{
		return "Like{"
			+ "tarih=" + tarih+ '}';
	}
}

Future
Future, zaman uyumsuz bir hesaplamanın sonucudur. Hesaplamanın tamamlanıp tamamlanmadığını belirlemek, tamamlanmasını beklemek ve hesaplamanın sonucunu almak için yöntemler sağlanır. Hesaplama tamamlandığında, sonuç yalnızca get yöntemi kullanılarak alınabilir, hazır olana kadar gerekirse engellenir. İptal yöntemi, bir işlemi iptal etmek için kullanılır. Görevin normal şekilde tamamlanıp tamamlanmadığını belirlemek için ek yöntemler sağlanır. Bir hesaplama tamamlandıktan sonra iptal edilemez. İptal edilebilirlik için bir Gelecek kullanmak istiyor ancak kullanılabilir bir sonuç sağlamak istemiyorsanız, Gelecek diyebilir misiniz? türleri ve temel alınan görevin sonucu olarak null değerini döndürün. Future arabirimini uyguladığından, başladıktan sonra iş parçacığı ile tüm etkileşimler FutureTask nesnesi tarafından işlenir. Sonuç olarak, Thread nesnelerini kaydetmeye gerek yoktur. FutureTask nesnesi görevi iptal etmek, tamamlanıp tamamlanmadığını denetlemek veya sonucu almayı denemek için kullanılabilir.

public class RemoteService {
	private static int cores
		= Runtime.getRuntime().availableProcessors();
	private static ExecutorService executor
		= Executors.newFixedThreadPool(cores + 1);
	public void stop() { executor.shutdown(); }
	public void
	getUserRecentGfgActs(ResultCallback callback)
	{
		executor.execute(() -> {
			List<Like> gfgLikes = new ArrayList<>();
			List<Post> gfgPOsts = new ArrayList<>();
			List<Comment> comments = new ArrayList<>();
			List<Friend> gfgCourses = new ArrayList<>();
			Future<List<Like> > futureGfgLikes
				= executor.submit(getGfgLikes(
					"https://geeksforgeeks.org.com/gfgLikes"));
			Future<List<Comment> > futureComments
				= executor.submit(getComments(
					"https://geeksforgeeks.org.com/comments"));
			Future<List<Post> > futureGfgPOsts
				= executor.submit(getGfgPOsts(
					"https://geeksforgeeks.org.com/gfgPOsts"));
			Future<List<Friend> > futureGfgCourses
				= executor.submit(getGfgCourses(
					"https://geeksforgeeks.org.com/gfgCourses"));

			try {
				gfgLikes = futureGfgLikes.get();
			}
			catch (InterruptedException
				| ExecutionException e) {
				e.printStackTrace();
			}

			try {
				gfgPOsts = futureGfgPOsts.get();
			}
			catch (InterruptedException
				| ExecutionException e) {
				e.printStackTrace();
			}

			try {
				comments = futureComments.get();
			}
			catch (InterruptedException
				| ExecutionException e) {
				e.printStackTrace();
			}

			try {
				gfgCourses = futureGfgCourses.get();
			}
			catch (InterruptedException
				| ExecutionException e) {
				e.printStackTrace();
			}

			List<Activity> gfgActs = new ArrayList<>();
			gfgActs.addAll(gfgLikes);
			gfgActs.addAll(gfgPOsts);
			gfgActs.addAll(comments);
			gfgActs.addAll(gfgCourses);

			Collections.sort(
				gfgActs,
				(activity1, activity2)
					-> activity1.getCreatedAt().compareTo(
						activity2.getCreatedAt()));

			callback.onResult(gfgActs);
		});
	}

	private Callable<List<Like> > getGfgLikes(String url)
	{
		return () ->
		{
			System.out.println("getGfgLikes");
			Thread.sleep(200);
			return Arrays.asList(
				new Like(new Date(1534334348560L)),
				new Like(new Date(1554365436546960L)));
		};
	}

	private Callable<List<Post> > getGfgPOsts(String url)
	{
		return () ->
		{
			System.out.println("getGfgPOsts");
			Thread.sleep(500);
			return Arrays.asList(
				new Post(new Date(15334343448560L)),
				new Post(new Date(153343434460L)));
		};
	}

	private Callable<List<Comment> > getComments(String url)
	{
		return () ->
		{
			System.out.println("getComments");
			Thread.sleep(200);
			return Arrays.asList(
				new Comment(new Date(15356565648560L)),
				new Comment(new Date(151454545456460L)));
		};
	}

	private Callable<List<Friend> >
	getGfgCourses(String url)
	{
		return () ->
		{
			System.out.println("getGfgCourses");
			Thread.sleep(6500);
			return Arrays.asList(
				new Friend(new Date(1534543354248560L)),
				new Friend(new Date(15334343546460L)));
		};
	}
}

Executor
Gönderilmiş olan Runnable görevlerini yürüten bir nesne. Bu arabirim, görev gönderimini, iş parçacığı kullanımı, zamanlama vb. gibi her görevin nasıl yürütüleceğine ilişkin mekaniklerden ayırmanıza olanak tanır. Açıkça iş parçacıkları oluşturmak yerine, genellikle bir Yürütücü kullanılır. Örneğin, yeni İş Parçacığı (new(RunnableTask())) çağırmak yerine. start() bir dizideki her görev için. Adından da anlaşılacağı gibi, sabit sayıda iş parçacığı içeren bir iş parçacığı havuzudur. Yürütücüye gönderilen görevler n iş parçacığı tarafından yürütülür ve ek görevler bir LinkedBlockingQueue üzerinde depolanır. Bir Engelleme Kuyruğu kullanır.

Bir görev oluşturacağımız ve sabit bir havuzda çalıştıracağımız Basit Bir Yürütücü Oluşturma ve Çalıştırma.

  1. Task sınıfı Callable’ı uygular ve bir String parametresine sahiptir. Ayrıca bir istisna oluşturacağı da belirtiliyor.
  2. “Task” sınıfındaki bir görevi yürütmek için önce Task sınıfının örneğini oluşturmalı ve yürütülmek üzere yürütücüye geçirmeliyiz.
  3. Future nesnesinin sonucu yazdırılmalı ve görüntülenmelidir.