CodeGym /ื‘ืœื•ื’ Java /Random-HE /ืขื“ื™ืฃ ื‘ื™ื—ื“: Java ื•ื›ื™ืชื” Thread. ื—ืœืง V - ืžื‘ืฆืข, ThreadPool, F...
John Squirrels
ืจึธืžึธื”
San Francisco

ืขื“ื™ืฃ ื‘ื™ื—ื“: Java ื•ื›ื™ืชื” Thread. ื—ืœืง V - ืžื‘ืฆืข, ThreadPool, Fork/Join

ืคื•ืจืกื ื‘ืงื‘ื•ืฆื”

ืžื‘ื•ื

ืื–, ืื ื—ื ื• ื™ื•ื“ืขื™ื ืฉืœื’'ืื•ื•ื” ื™ืฉ ื—ื•ื˜ื™ื. ืืชื” ื™ื›ื•ืœ ืœืงืจื•ื ืขืœ ื›ืš ื‘ืกืงื™ืจื” ืฉื›ื•ืชืจืชื” Better together: Java and the Thread class. ื—ืœืง ื' - ื—ื•ื˜ื™ ื”ื•ืฆืื” ืœื”ื•ืจื’ . ืขื“ื™ืฃ ื‘ื™ื—ื“: Java ื•ื›ื™ืชื” Thread.  ื—ืœืง V - ืžื‘ืฆืข, ThreadPool, Fork/Join - 1ื‘ื•ืื• ื ืกืชื›ืœ ืฉื•ื‘ ืขืœ ื”ืงื•ื“ ื”ื˜ื™ืคื•ืกื™:
public static void main(String[] args) throws Exception {
	Runnable task = () -> {
		System.out.println("Task executed");
	};
	Thread thread = new Thread(task);
	thread.start();
}
ื›ืคื™ ืฉืืชื” ื™ื›ื•ืœ ืœืจืื•ืช, ื”ืงื•ื“ ื›ื“ื™ ืœื”ืชื—ื™ืœ ืžืฉื™ืžื” ื”ื•ื ื“ื™ ืื•ืคื™ื™ื ื™, ืื‘ืœ ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื—ื–ื•ืจ ืขืœื™ื• ืขื‘ื•ืจ ืžืฉื™ืžื” ื—ื“ืฉื”. ืคืชืจื•ืŸ ืื—ื“ ื”ื•ื ืœืฉื™ื ืื•ืชื• ื‘ืฉื™ื˜ื” ื ืคืจื“ืช, ืœืžืฉืœ execute(Runnable runnable). ืื‘ืœ ื”ื™ื•ืฆืจื™ื ืฉืœ ื’'ืื•ื•ื” ืฉืงืœื• ืืช ืžืฆื•ืงืชื ื• ื•ื”ื’ื™ืขื• ืœืžืžืฉืง Executor:
public static void main(String[] args) throws Exception {
	Runnable task = () -> System.out.println("Task executed");
	Executor executor = (runnable) -> {
		new Thread(runnable).start();
	};
	executor.execute(task);
}
ื‘ืจื•ืจ ืฉื”ืงื•ื“ ื”ื–ื” ื”ื•ื ืชืžืฆื™ืชื™ ื™ื•ืชืจ: ืขื›ืฉื™ื• ืื ื—ื ื• ืคืฉื•ื˜ ื›ื•ืชื‘ื™ื ืงื•ื“ ื›ื“ื™ ืœื”ืชื—ื™ืœ ืืช Runnableื”ืฉืจืฉื•ืจ. ื–ื” ื ื”ื“ืจ, ืœื? ืื‘ืœ ื–ื• ืจืง ื”ื”ืชื—ืœื”: ืขื“ื™ืฃ ื‘ื™ื—ื“: Java ื•ื›ื™ืชื” Thread.  ื—ืœืง V - ืžื‘ืฆืข, ThreadPool, Fork/Join - 2

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html

ื›ืคื™ ืฉื ื™ืชืŸ ืœืจืื•ืช, Executorืœืžืžืฉืง ื™ืฉ ืžืžืฉืง ExecutorServiceืžืฉื ื”. ื”-Javadoc ืขื‘ื•ืจ ืžืžืฉืง ื–ื” ืื•ืžืจ ืฉืžืชืืจ ExecutorServiceืคืจื˜ Executorื”ืžืกืคืง ืฉื™ื˜ื•ืช ืœื›ื™ื‘ื•ื™ ื”- Executor. ื–ื” ื’ื ืžืืคืฉืจ ืœืงื‘ืœ java.util.concurrent.Futureืขืœ ืžื ืช ืœืขืงื•ื‘ ืื—ืจ ืชื”ืœื™ืš ื”ื‘ื™ืฆื•ืข. ื‘ืขื‘ืจ, ื‘- Better together: Java and the Thread class. ื—ืœืง IV - ื ื™ืชืŸ ืœื”ืชืงืฉืจื•ืช, ืขืชื™ื“ ื•ื—ื‘ืจื™ื , ืกืงืจื ื• ื‘ืงืฆืจื” ืืช ื”ื™ื›ื•ืœื•ืช ืฉืœ Future. ืื ืฉื›ื—ืช ืื• ืืฃ ืคืขื ืœื ืงืจืืช ืื•ืชื•, ืื ื™ ืžืฆื™ืข ืœืš ืœืจืขื ืŸ ืืช ื”ื–ื™ื›ืจื•ืŸ ;) ืžื” ืขื•ื“ ืื•ืžืจ ื”-Javadoc? ื–ื” ืื•ืžืจ ืœื ื• ืฉื™ืฉ ืœื ื• java.util.concurrent.Executorsืžืคืขืœ ืžื™ื•ื—ื“ ืฉืžืืคืฉืจ ืœื ื• ืœื™ืฆื•ืจ ื™ื™ืฉื•ืžื™ ื‘ืจื™ืจืช ืžื—ื“ืœ ืฉืœ ExecutorService.

ExecutorService

ื‘ื•ืื• ื ืกืงื•ืจ. ืขืœื™ื ื• Executorืœื‘ืฆืข (ื›ืœื•ืžืจ ืœื”ืชืงืฉืจ execute()) ืžืฉื™ืžื” ืžืกื•ื™ืžืช ื‘ืฉืจืฉื•ืจ, ื•ื”ืงื•ื“ ืฉื™ื•ืฆืจ ืืช ื”ืฉืจืฉื•ืจ ืžื•ืกืชืจ ืžืื™ืชื ื•. ื™ืฉ ืœื ื• ExecutorService- ืกืคืฆื™ืคื™ Executorืฉื™ืฉ ืœื• ืžืกืคืจ ืืคืฉืจื•ื™ื•ืช ืœืฉืœื™ื˜ื” ื‘ื”ืชืงื“ืžื•ืช. ื•ื™ืฉ ืœื ื• ืืช Executorsื”ืžืคืขืœ ืฉืžืืคืฉืจ ืœื ื• ืœื™ืฆื•ืจ ExecutorService. ืขื›ืฉื™ื• ื‘ื•ืื• ื ืขืฉื” ื–ืืช ื‘ืขืฆืžื ื•:
public static void main(String[] args) throws ExecutionException, InterruptedException {
	Callable<String> task = () -> Thread.currentThread().getName();
	ExecutorService service = Executors.newFixedThreadPool(2);
	for (int i = 0; i < 5; i++) {
		Future result = service.submit(task);
		System.out.println(result.get());
	}
	service.shutdown();
}
ื ื™ืชืŸ ืœืจืื•ืช ืฉืฆื™ื™ื ื• ืžืื’ืจ ื—ื•ื˜ื™ื ืงื‘ื•ืข ืฉื’ื•ื“ืœื• ื”ื•ื 2. ืœืื—ืจ ืžื›ืŸ ืื ื• ืžื’ื™ืฉื™ื ืžืฉื™ืžื•ืช ืœืžืื’ืจ ืื—ื“ ืื—ื“. ื›ืœ ืžืฉื™ืžื” ืžื—ื–ื™ืจื” a Stringื”ืžื›ื™ืœ ืืช ืฉื ื”ืฉืจืฉื•ืจ ( currentThread().GetName()). ื—ืฉื•ื‘ ืœืกื’ื•ืจ ืืช ื”ืชื•ื›ื ื™ืช ExecutorServiceืžืžืฉ ื‘ืกื•ืฃ, ื›ื™ ืื—ืจืช ื”ืชื•ื›ื ื™ืช ืฉืœื ื• ืœื ืชืกืชื™ื™ื. ืœืžืคืขืœ Executorsืฉื™ื˜ื•ืช ืžืคืขืœ ื ื•ืกืคื•ืช. ืœื“ื•ื’ืžื”, ื ื•ื›ืœ ืœื™ืฆื•ืจ ื‘ืจื™ื›ื” ื”ืžื•ืจื›ื‘ืช ืžืฉืจืฉื•ืจ ืื—ื“ ื‘ืœื‘ื“ ( newSingleThreadExecutor) ืื• ืžืื’ืจ ื”ื›ื•ืœืœ ืžื˜ืžื•ืŸ ( newCachedThreadPool) ืฉืžืžื ื• ืžื•ืกืจื™ื ืฉืจืฉื•ืจื™ื ืœืื—ืจ ืฉื”ื ืœื ืคืขื™ืœื™ื ื‘ืžืฉืš ื“ืงื”. ื‘ืžืฆื™ืื•ืช, ืืœื” ExecutorServiceืžื’ื•ื‘ื™ื ื‘ืชื•ืจ ื—ืกื™ืžื” , ืฉืœืชื•ื›ื• ืžืžื•ืงืžื•ืช ืžืฉื™ืžื•ืช ื•ืžืžื ื• ืžื‘ื•ืฆืขื•ืช ืžืฉื™ืžื•ืช. ืžื™ื“ืข ื ื•ืกืฃ ืขืœ ื—ืกื™ืžืช ืชื•ืจื™ื ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืกืจื˜ื•ืŸ ื–ื” . ืืชื” ื™ื›ื•ืœ ื’ื ืœืงืจื•ื ืกืงื™ืจื” ื–ื• ืขืœ BlockingQueue . ื•ื‘ื“ื•ืง ืืช ื”ืชืฉื•ื‘ื” ืœืฉืืœื” "ืžืชื™ ืœื”ืขื“ื™ืฃ LinkedBlockingQueue ืขืœ ืคื ื™ ArrayBlockingQueue?" ื‘ืžื•ื ื—ื™ื ื”ืคืฉื•ื˜ื™ื ื‘ื™ื•ืชืจ, a BlockingQueueื—ื•ืกื ื—ื•ื˜ ื‘ืฉื ื™ ืžืงืจื™ื:
  • ื”ืฉืจืฉื•ืจ ืžื ืกื” ืœื”ืฉื™ื’ ืคืจื™ื˜ื™ื ืžืชื•ืจ ืจื™ืง
  • ื”ืฉืจืฉื•ืจ ืžื ืกื” ืœื”ื›ื ื™ืก ืคืจื™ื˜ื™ื ืœืชื•ืจ ืžืœื
ืื ื ืกืชื›ืœ ืขืœ ื™ื™ืฉื•ื ืฉื™ื˜ื•ืช ื”ืžืคืขืœ, ื ื•ื›ืœ ืœืจืื•ืช ื›ื™ืฆื“ ื”ืŸ ืคื•ืขืœื•ืช. ืœื“ื•ื’ืžื”:
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
}
ืื•ึน
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}
ื›ืคื™ ืฉืื ื• ื™ื›ื•ืœื™ื ืœืจืื•ืช, ื™ื™ืฉื•ืžื™ื ืฉืœ ExecutorServiceื ื•ืฆืจื™ื ื‘ืชื•ืš ืฉื™ื˜ื•ืช ื”ืžืคืขืœ. ื•ืœืจื•ื‘, ืื ื—ื ื• ืžื“ื‘ืจื™ื ืขืœ ThreadPoolExecutor. ืจืง ื”ืคืจืžื˜ืจื™ื ื”ืžืฉืคื™ืขื™ื ืขืœ ื”ืขื‘ื•ื“ื” ืžืฉืชื ื™ื. ืขื“ื™ืฃ ื‘ื™ื—ื“: Java ื•ื›ื™ืชื” Thread.  ื—ืœืง V - ืžื‘ืฆืข, ThreadPool, Fork/Join - 3

https://en.wikipedia.org/wiki/Thread_pool#/media/File:Thread_pool.svg

ThreadPoolExecutor

ื›ืคื™ ืฉืจืื™ื ื• ืงื•ื“ื, ThreadPoolExecutorื–ื” ืžื” ืฉื‘ื“ืจืš ื›ืœืœ ื ื•ืฆืจ ื‘ืชื•ืš ืฉื™ื˜ื•ืช ื”ืžืคืขืœ. ื”ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ืžื•ืฉืคืขืช ืžื”ืืจื’ื•ืžื ื˜ื™ื ืฉืื ื• ืžืขื‘ื™ืจื™ื ื›ืžืกืคืจ ื”ืžืจื‘ื™ ื•ื”ืžื™ื ื™ืžืœื™ ืฉืœ ืฉืจืฉื•ืจื™ื, ื›ืžื• ื’ื ืžืื™ื–ื” ืกื•ื’ ืชื•ืจ ื ืขืฉื” ืฉื™ืžื•ืฉ. ืื‘ืœ java.util.concurrent.BlockingQueueื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘ื›ืœ ื™ื™ืฉื•ื ืฉืœ ื”ืžืžืฉืง. ืื ื›ื‘ืจ ืžื“ื‘ืจื™ื ืขืœ ThreadPoolExecutor, ืขืœื™ื ื• ืœื”ื–ื›ื™ืจ ื›ืžื” ืชื›ื•ื ื•ืช ืžืขื ื™ื™ื ื•ืช. ืœื“ื•ื’ืžื”, ืœื ื ื™ืชืŸ ืœืฉืœื•ื— ืžืฉื™ืžื•ืช ืœ- ThreadPoolExecutorืื ืื™ืŸ ืžืงื•ื ืคื ื•ื™:
public static void main(String[] args) throws ExecutionException, InterruptedException {
	int threadBound = 2;
	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, threadBound,
            0L, TimeUnit.SECONDS, new SynchronousQueue<>());
	Callable<String> task = () -> {
		Thread.sleep(1000);
		return Thread.currentThread().getName();
	};
	for (int i = 0; i < threadBound + 1; i++) {
		threadPoolExecutor.submit(task);
	}
	threadPoolExecutor.shutdown();
}
ื”ืงื•ื“ ื”ื–ื” ื™ืงืจื•ืก ืขื ืฉื’ื™ืื” ื›ื–ื•:
Task java.util.concurrent.FutureTask@7cca494b rejected from java.util.concurrent.ThreadPoolExecutor@7ba4f24f[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]
ื‘ืžื™ืœื™ื ืื—ืจื•ืช, taskืœื ื ื™ืชืŸ ืœื”ื’ื™ืฉ, ื›ื™ SynchronousQueueื”ื•ื ืžืชื•ื›ื ืŸ ื›ืš ืฉื”ื•ื ืœืžืขืฉื” ืžื•ืจื›ื‘ ืžืืœืžื ื˜ ื‘ื•ื“ื“ ื•ืœื ืžืืคืฉืจ ืœื ื• ืœื”ื›ื ื™ืก ื‘ื• ืฉื•ื ื“ื‘ืจ ื ื•ืกืฃ. ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœืจืื•ืช ืฉื™ืฉ ืœื ื• ืืคืก queued tasks("ืžืฉื™ืžื•ืช ื‘ืชื•ืจ = 0") ื›ืืŸ. ืื‘ืœ ืื™ืŸ ื‘ื–ื” ืฉื•ื ื“ื‘ืจ ืžื•ื–ืจ, ื›ื™ ื–ื• ืชื›ื•ื ื” ืžื™ื•ื—ื“ืช ืฉืœ SynchronousQueue, ืฉืœืžืขืฉื” ื”ื™ื ืชื•ืจ ืฉืœ ืืœืžื ื˜ ืื—ื“ ืฉืชืžื™ื“ ืจื™ืง! ื›ืืฉืจ ืฉืจืฉื•ืจ ืื—ื“ ืžื›ื ื™ืก ืืœืžื ื˜ ืœืชื•ืจ, ื”ื•ื ื™ืžืชื™ืŸ ืขื“ ืฉืจืฉื•ืจ ืื—ืจ ื™ื™ืงื— ืืช ื”ืืœืžื ื˜ ืžื”ืชื•ืจ. ื‘ื”ืชืื ืœื›ืš, ื ื•ื›ืœ ืœื”ื—ืœื™ืฃ ืื•ืชื• ื‘- new LinkedBlockingQueue<>(1)ื•ื”ืฉื’ื™ืื” ืชืฉืชื ื” ืœื”ืฆื’ืช ื›ืขืช queued tasks = 1. ืžื›ื™ื•ื•ืŸ ืฉื”ืชื•ืจ ื”ื•ื ืจืง ืืœืžื ื˜ ืื—ื“, ืื ื—ื ื• ืœื ื™ื›ื•ืœื™ื ืœื”ื•ืกื™ืฃ ืืœืžื ื˜ ืฉื ื™. ื•ื–ื” ืžื” ืฉื’ื•ืจื ืœืชื•ื›ื ื™ืช ืœื”ื™ื›ืฉืœ. ื‘ื”ืžืฉืš ื”ื“ื™ื•ืŸ ืฉืœื ื• ืขืœ ืชื•ืจ, ืจืื•ื™ ืœืฆื™ื™ืŸ ืฉืœื›ื™ืชื” ThreadPoolExecutorื™ืฉ ืฉื™ื˜ื•ืช ื ื•ืกืคื•ืช ืœืฉื™ืจื•ืช ื”ืชื•ืจ. ืœื“ื•ื’ืžื”, threadPoolExecutor.purge()ื”ืฉื™ื˜ื” ืชืกื™ืจ ืืช ื›ืœ ื”ืžืฉื™ืžื•ืช ืฉื‘ื•ื˜ืœื• ืžื”ืชื•ืจ ืขืœ ืžื ืช ืœืคื ื•ืช ืžืงื•ื ื‘ืชื•ืจ. ืคื•ื ืงืฆื™ื” ืžืขื ื™ื™ื ืช ื ื•ืกืคืช ื”ืงืฉื•ืจื” ืœืชื•ืจ ื”ื™ื ื”ืžื˜ืคืœ ืœืžืฉื™ืžื•ืช ืฉื ื“ื—ื•:
public static void main(String[] args) {
	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1,
            0L, TimeUnit.SECONDS, new SynchronousQueue());
	Callable<String> task = () -> Thread.currentThread().getName();
	threadPoolExecutor.setRejectedExecutionHandler((runnable, executor) -> System.out.println("Rejected"));
	for (int i = 0; i < 5; i++) {
		threadPoolExecutor.submit(task);
	}
	threadPoolExecutor.shutdown();
}
ื‘ื“ื•ื’ืžื” ื–ื•, ื”ืžื˜ืคืœ ืฉืœื ื• ืคืฉื•ื˜ ืžืฆื™ื’ Rejectedื‘ื›ืœ ืคืขื ืฉืžืฉื™ืžื” ื‘ืชื•ืจ ื ื“ื—ื™ืช. ื ื•ื—, ืœื? ื‘ื ื•ืกืฃ, ThreadPoolExecutorื™ืฉ ืชืช-ืžื—ืœืงื” ืžืขื ื™ื™ื ืช: ScheduledThreadPoolExecutor, ืฉื”ื™ื ScheduledExecutorService. ื”ื•ื ืžืกืคืง ืืช ื”ื™ื›ื•ืœืช ืœื‘ืฆืข ืžืฉื™ืžื” ืขืœ ื‘ืกื™ืก ื˜ื™ื™ืžืจ.

ScheduledExecutorService

ScheduledExecutorService(ืฉื–ื” ืกื•ื’ ืฉืœ ExecutorService) ืžืืคืฉืจ ืœื ื• ืœื”ืจื™ืฅ ืžืฉื™ืžื•ืช ืœืคื™ ืœื•ื— ื–ืžื ื™ื. ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื“ื•ื’ืžื”:
public static void main(String[] args) {
	ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(4);
	Callable<String> task = () -> {
		System.out.println(Thread.currentThread().getName());
		return Thread.currentThread().getName();
	};
	scheduledExecutorService.schedule(task, 1, TimeUnit.MINUTES);
	scheduledExecutorService.shutdown();
}
ื”ื›ืœ ืคืฉื•ื˜ ื›ืืŸ. ื”ืžืฉื™ืžื•ืช ืžื•ื’ืฉื•ืช ื•ืื– ืื ื—ื ื• ืžืงื‘ืœื™ื java.util.concurrent.ScheduledFuture. ืœื•ื— ื–ืžื ื™ื ืขืฉื•ื™ ืœื”ื™ื•ืช ืžื•ืขื™ืœ ื’ื ื‘ืžืฆื‘ ื”ื‘ื:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(4);
Runnable task = () -> {
	System.out.println(Thread.currentThread().getName());
};
scheduledExecutorService.scheduleAtFixedRate(task, 1, 2, TimeUnit.SECONDS);
ื›ืืŸ ืื ื• ืžื’ื™ืฉื™ื Runnableืžืฉื™ืžื” ืœื‘ื™ืฆื•ืข ื‘ืชื“ื™ืจื•ืช ืงื‘ื•ืขื” ("FixedRate") ืขื ืขื™ื›ื•ื‘ ืจืืฉื•ื ื™ ืžืกื•ื™ื. ื‘ืžืงืจื” ื–ื”, ืœืื—ืจ ืฉื ื™ื™ื” ืื—ืช, ื”ืžืฉื™ืžื” ืชืชื—ื™ืœ ืœื”ืชื‘ืฆืข ื›ืœ 2 ืฉื ื™ื•ืช. ื™ืฉ ืืคืฉืจื•ืช ื“ื•ืžื”:
scheduledExecutorService.scheduleWithFixedDelay(task, 1, 2, TimeUnit.SECONDS);
ืื‘ืœ ื‘ืžืงืจื” ื–ื”, ื”ืžืฉื™ืžื•ืช ืžื‘ื•ืฆืขื•ืช ืขื ืžืจื•ื•ื— ืžืกื•ื™ื ื‘ื™ืŸ ื›ืœ ื‘ื™ืฆื•ืข. ื›ืœื•ืžืจ, ื”ืฆื•ื•ืื” taskืชืชื‘ืฆืข ืœืื—ืจ ืฉื ื™ื™ื” ืื—ืช. ืœืื—ืจ ืžื›ืŸ, ื‘ืจื’ืข ืฉื”ื™ื ืชื•ืฉืœื, ื™ืขื‘ืจื• 2 ืฉื ื™ื•ืช, ื•ืื– ืชืชื—ื™ืœ ืžืฉื™ืžื” ื—ื“ืฉื”. ืœื”ืœืŸ ืžืกืคืจ ืžืฉืื‘ื™ื ื ื•ืกืคื™ื ื‘ื ื•ืฉื ื–ื”: ืขื“ื™ืฃ ื‘ื™ื—ื“: Java ื•ื›ื™ืชื” Thread.  ื—ืœืง V - ืžื‘ืฆืข, ThreadPool, Fork/Join - 4

https://dzone.com/articles/diving-into-java-8s-newworkstealingpools

WorkStealingPool

ื‘ื ื•ืกืฃ ืœื‘ืจื™ื›ื•ืช ื”ื—ื•ื˜ื™ื ื”ื "ืœ, ื™ืฉ ืขื•ื“ ืื—ืช. ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœื•ืžืจ ื‘ื›ื ื•ืช ืฉื–ื” ืงืฆืช ืžื™ื•ื—ื“. ื–ื” ื ืงืจื ื‘ืจื™ื›ืช ื’ื ื™ื‘ืช ืขื‘ื•ื“ื”. ื‘ืงื™ืฆื•ืจ, ื’ื ื™ื‘ืช ืขื‘ื•ื“ื” ื”ื™ื ืืœื’ื•ืจื™ืชื ืฉื‘ื• ืฉืจืฉื•ืจื™ื ืกืจืง ืžืชื—ื™ืœื™ื ืœืงื—ืช ืžืฉื™ืžื•ืช ืžืฉืจืฉื•ืจื™ื ืื—ืจื™ื ืื• ืžืฉื™ืžื•ืช ืžืชื•ืจ ืžืฉื•ืชืฃ. ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื“ื•ื’ืžื”:
public static void main(String[] args) {
	Object lock = new Object();
	ExecutorService executorService = Executors.newCachedThreadPool();
	Callable<String> task = () -> {
		System.out.println(Thread.currentThread().getName());
		lock.wait(2000);
		System.out.println("Finished");
		return "result";
	};
	for (int i = 0; i < 5; i++) {
		executorService.submit(task);
	}
	executorService.shutdown();
}
ืื ื ืจื™ืฅ ืืช ื”ืงื•ื“ ื”ื–ื”, ืื– ื–ื” ExecutorServiceื™ื™ืฆื•ืจ ืขื‘ื•ืจื ื• 5 ืฉืจืฉื•ืจื™ื, ืžื›ื™ื•ื•ืŸ ืฉื›ืœ ืฉืจืฉื•ืจ ื™ื•ื›ื ืก ืœืชื•ืจ ื”ื”ืžืชื ื” ืœืื•ื‘ื™ื™ืงื˜ ื”ื ืขื™ืœื”. ื›ื‘ืจ ื’ื™ืœื™ื ื• ืฆื’ื™ื ื•ืžื ืขื•ืœื™ื ื‘- Better ื‘ื™ื—ื“: Java ื•ืžื—ืœืงืช Thread. ื—ืœืง ื‘' - ืกื ื›ืจื•ืŸ . ืขื›ืฉื™ื• ื‘ื•ืื• ื ื—ืœื™ืฃ Executors.newCachedThreadPool()ื‘ Executors.newWorkStealingPool(). ืžื” ื™ืฉืชื ื”? ื ืจืื” ืฉื”ืžืฉื™ืžื•ืช ืฉืœื ื• ืžื‘ื•ืฆืขื•ืช ื‘ืคื—ื•ืช ืž-5 ืฉืจืฉื•ืจื™ื. ื–ื•ื›ืจื™ื ืฉื–ื” CachedThreadPoolื™ื•ืฆืจ ืฉืจืฉื•ืจ ืœื›ืœ ืžืฉื™ืžื”? ื”ืกื™ื‘ื” ืœื›ืš ื”ื™ื wait()ืฉื—ืกืžื” ืืช ื”ืฉืจืฉื•ืจ, ืžืฉื™ืžื•ืช ืขื•ืงื‘ื•ืช ืจื•ืฆื•ืช ืœื”ืกืชื™ื™ื, ื•ื ื•ืฆืจื• ืขื‘ื•ืจืŸ ืฉืจืฉื•ืจื™ื ื—ื“ืฉื™ื ื‘ืžืื’ืจ. ืขื ื‘ืจื™ื›ื” ื’ื ื™ื‘ื”, ื—ื•ื˜ื™ื ืœื ืขื•ืžื“ื™ื ื‘ื˜ืœื™ื ืœื ืฆื—. ื”ื ืžืชื—ื™ืœื™ื ืœื‘ืฆืข ืืช ื”ืžืฉื™ืžื•ืช ืฉืœ ืฉื›ื ื™ื”ื. ืžื” ืขื•ืฉื” WorkStealingPoolื›ืœ ื›ืš ืฉื•ื ื” ืžื‘ืจื™ื›ื•ืช ื—ื•ื˜ื™ื ืื—ืจื•ืช? ื”ืขื•ื‘ื“ื” ืฉื”ืงืกื•ื ForkJoinPoolื—ื™ ื‘ืชื•ื›ื•:
public static ExecutorService newWorkStealingPool() {
        return new ForkJoinPool
            (Runtime.getRuntime().availableProcessors(),
             ForkJoinPool.defaultForkJoinWorkerThreadFactory,
             null, true);
}
ืœืžืขืฉื”, ื™ืฉ ืขื•ื“ ื”ื‘ื“ืœ ืื—ื“. ื›ื‘ืจื™ืจืช ืžื—ื“ืœ, ื”ืฉืจืฉื•ืจื™ื ืฉื ื•ืฆืจื• ืขื‘ื•ืจ a ForkJoinPoolื”ื ืฉืจืฉื•ืจื™ ื“ืžื•ืŸ, ื‘ืฉื•ื ื” ืžื”ืฉืจืฉื•ืจื™ื ืฉื ื•ืฆืจื• ื‘ืืžืฆืขื•ืช ืฉืจืฉื•ืจ ืจื’ื™ืœ ThreadPool. ื‘ืื•ืคืŸ ื›ืœืœื™, ืืชื” ืฆืจื™ืš ืœื–ื›ื•ืจ ืฉืจืฉื•ืจื™ ื“ืžื•ืŸ, ืžื›ื™ื•ื•ืŸ, ืœืžืฉืœ, CompletableFutureืžืฉืชืžืฉ ื’ื ื‘ืฉืจืฉื•ืจื™ ื“ืžื•ืŸ ืืœื ืื ื›ืŸ ืืชื” ืžืฆื™ื™ืŸ ืžืฉืœืš ThreadFactoryืฉื™ื•ืฆืจ ืฉืจืฉื•ืจื™ื ืฉืื™ื ื ื“ืžื•ื ื™ื. ืืœื• ื”ื”ืคืชืขื•ืช ืฉืขืœื•ืœื•ืช ืœื”ื™ื•ืช ืื•ืจื‘ื•ืช ื‘ืžืงื•ืžื•ืช ืœื ืฆืคื•ื™ื™ื! :)

ForkJoinPool

ื‘ื—ืœืง ื–ื”, ื ื“ื‘ืจ ืฉื•ื‘ ืขืœ ForkJoinPool(ื”ื ืงืจืืช ื’ื ืžืกื’ืจืช ื”ืžื–ืœื’/ื”ื—ื‘ืจ), ืฉื—ื™ "ืžืชื—ืช ืœืžื›ืกื” ื”ืžื ื•ืข" ืฉืœ WorkStealingPool. ื‘ืื•ืคืŸ ื›ืœืœื™, ื”ืžืกื’ืจืช fork/join ื”ื•ืคื™ืขื” ื‘ื—ื–ืจื” ื‘-Java 1.7. ื•ืœืžืจื•ืช ืฉ-Java 11 ืงืจื•ื‘ื”, ืขื“ื™ื™ืŸ ื›ื“ืื™ ืœื–ื›ื•ืจ ืื•ืชื”. ื–ื” ืœื ื”ื™ื™ืฉื•ื ื”ื ืคื•ืฅ ื‘ื™ื•ืชืจ, ืื‘ืœ ื”ื•ื ื“ื™ ืžืขื ื™ื™ืŸ. ื™ืฉ ืกืงื™ืจื” ื˜ื•ื‘ื” ืขืœ ื–ื” ื‘ืื™ื ื˜ืจื ื˜: ื”ื‘ื ืช Java Fork-Join Framework ืขื ื“ื•ื’ืžืื•ืช . ื”ืžืกืชืžื›ืช ForkJoinPoolืขืœ java.util.concurrent.RecursiveTask. ื™ืฉ ื’ื java.util.concurrent.RecursiveAction. RecursiveActionืœื ืžื—ื–ื™ืจ ืชื•ืฆืื”. ืœืคื™ื›ืš, RecursiveTaskื“ื•ืžื” ืœ Callable, ื•ื“ื•ืžื” RecursiveActionืœ unnable. ืื ื• ื™ื›ื•ืœื™ื ืœืจืื•ืช ืฉื”ืฉื ื›ื•ืœืœ ืฉืžื•ืช ืฉืœ ืฉืชื™ ืฉื™ื˜ื•ืช ื—ืฉื•ื‘ื•ืช: forkื• join. ื”ืฉื™ื˜ื” forkืžืชื—ื™ืœื” ืžืฉื™ืžื” ื›ืœืฉื”ื™ ื‘ืื•ืคืŸ ืืกื™ื ื›ืจื•ื ื™ ื‘ืฉืจืฉื•ืจ ื ืคืจื“. ื•ื”ืฉื™ื˜ื” joinืžืืคืฉืจืช ืœืš ืœื—ื›ื•ืช ืœืขื‘ื•ื“ื” ืฉืชืชื‘ืฆืข. ื›ื“ื™ ืœืงื‘ืœ ืืช ื”ื”ื‘ื ื” ื”ื˜ื•ื‘ื” ื‘ื™ื•ืชืจ, ื›ื“ืื™ ืœืงืจื•ื ืžืชื›ื ื•ืช ืฆื™ื•ื•ื™ ืœ-Fork/Join ืœื–ืจืžื™ื ืžืงื‘ื™ืœื™ื ื‘-Java 8 .

ืกื™ื›ื•ื

ื•ื‘ื›ืŸ, ื–ื” ืžืกื›ื ืืช ื”ื—ืœืง ื”ื–ื” ืฉืœ ื”ืกืงื™ืจื”. ืœืžื“ื ื• ืฉื–ื” Executorื”ื•ืžืฆื ื‘ืžืงื•ืจ ื›ื“ื™ ืœื‘ืฆืข ืฉืจืฉื•ืจื™ื. ื•ืื– ื”ื™ื•ืฆืจื™ื ืฉืœ ื’'ืื•ื•ื” ื”ื—ืœื™ื˜ื• ืœื”ืžืฉื™ืš ื‘ืจืขื™ื•ืŸ ื•ื”ืขืœื• ExecutorService. ExecutorServiceืžืืคืฉืจ ืœื ื• ืœืฉืœื•ื— ืžืฉื™ืžื•ืช ืœื‘ื™ืฆื•ืข ื‘ืืžืฆืขื•ืช submit()ื• invoke(), ื•ื’ื ืœื›ื‘ื•ืช ืืช ื”ืฉื™ืจื•ืช. ืžื›ื™ื•ื•ืŸ ExecutorServiceืฉืฆืจื™ืš ื™ื™ืฉื•ืžื™ื, ื”ื ื›ืชื‘ื• ืžื—ืœืงื” ืขื ืฉื™ื˜ื•ืช ืžืคืขืœ ื•ืงืจืื• ืœื–ื” Executors. ื–ื” ืžืืคืฉืจ ืœืš ืœื™ืฆื•ืจ ื‘ืจื™ื›ื•ืช ื—ื•ื˜ื™ื ( ThreadPoolExecutor). ื‘ื ื•ืกืฃ, ื™ืฉื ื ื‘ืจื™ื›ื•ืช ืฉืจืฉื•ืจื™ื ื”ืžืืคืฉืจื•ืช ืœื ื• ื’ื ืœืฆื™ื™ืŸ ืœื•ื— ื–ืžื ื™ื ืœื‘ื™ืฆื•ืข. ื•ืžืกืชืชืจ ForkJoinPoolืžืื—ื•ืจื™ ื WorkStealingPool. ืื ื™ ืžืงื•ื•ื” ืฉืžืฆืืช ืืช ืžื” ืฉื›ืชื‘ืชื™ ืœืžืขืœื” ืœื ืจืง ืžืขื ื™ื™ืŸ, ืืœื ื’ื ืžื•ื‘ืŸ :) ืื ื™ ืชืžื™ื“ ืฉืžื— ืœืฉืžื•ืข ืืช ื”ื”ืฆืขื•ืช ื•ื”ื”ืขืจื•ืช ืฉืœืš. ืขื“ื™ืฃ ื‘ื™ื—ื“: Java ื•ื›ื™ืชื” Thread. ื—ืœืง ื' - ื—ื•ื˜ื™ ื‘ื™ืฆื•ืข ื˜ื•ื‘ ื™ื•ืชืจ ื‘ื™ื—ื“: ื’'ืื•ื•ื” ื•ืžื—ืœืงืช ื”-Thread. ื—ืœืง ื‘' - ืกื ื›ืจื•ืŸ ื˜ื•ื‘ ื™ื•ืชืจ ื‘ื™ื—ื“: Java ื•ืžื—ืœืงืช Thread. ื—ืœืง ืฉืœื™ืฉื™ - ืื™ื ื˜ืจืืงืฆื™ื” ื˜ื•ื‘ื” ื™ื•ืชืจ ื‘ื™ื—ื“: Java ื•ืžื—ืœืงืช Thread. ื—ืœืง IV โ€” ื ื™ืชืŸ ืœื”ืชืงืฉืจื•ืช, ืขืชื™ื“ ื•ื—ื‘ืจื™ื ื˜ื•ื‘ื™ื ื™ื•ืชืจ ื‘ื™ื—ื“: Java ื•ื›ื™ืชื” Thread. ื—ืœืง ื•' - ืืฉ!
ื”ืขืจื•ืช
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION