I will summarize what I do not understand. I'm sorry to post it even though I'm not sure. Please tell me who knows.
Concurrency in Java = multithreaded programming.
Thread is a class that handles threads. Start the thread with start. Since run runs in start, inherit Thread and Override run.
Runnable is the interface of the class that is the entry point. Pass it to Thread and have it run with start. Since it is an interface, implement and implement run.
Only the Thread class can start a new thread. The behavior is run. Whether to inherit Thread or implement Runnable is a matter of choosing Template Method pattern or Strategy pattern, and usually adopts Strategy pattern from the viewpoint of class dependency.
What I'm not sure about is that Thread implements the Runnable interface. Since it implements run, it seems that it is not wrong, but it is confusing. For normal use, forget about implementing Runnable. I don't know where it will be useful. There seems to be some controversy about this when Java 1.0 is released, which means it's hard to understand.
reference Kishida Hatena Thread and Runnable
Seiichi Yoshida's Homepage Java Threads and Memory Leaks
The Executor framework was introduced in Java 1.5 to take over the task of controlling Thread because it can no longer be used once it is used, and even if it is generated in large quantities, it puts pressure on resources. By giving control, programmers can focus on task design. "Controlling threads" means pooling threads according to the Worker Thread pattern so that they can work efficiently.
The Executor implements the Command pattern, so the thread can execute the task without being aware of it.
The Executor Service interface adds termination and tracking capabilities to the Executor. You can disable the acceptance of tasks with shutdown, and you can track tasks with the return value Future of submit.
Future class is an implementation of Future pattern. If you want to get Future by submit, pass Callable as a task. Callable is used much like Runnable. The only difference is whether or not you get the result with Submit. Callable does not inherit from Runnable. Submit can also receive Runnable, but the result seems to change (I'm not sure how it will change, Futuer is null?). If you submit, you can use Callable and there is no problem. The difference between Callable and Runnable is confusing. I wish I could return Future with Runnable. I don't understand because there is a RunnableFuture interface that is both Runnable and Future.
Executor and ExecutorService are usually not implemented by yourself. Get Executors as a factory. Since there is a Scheduled Executor Service etc., I checked API. Executors also have a Runnable to Callable converter, so I think Callable is a Runnable.
Also, this is like talking with a pattern name, so it's hard if you don't know the design pattern.
reference Notepad for programmers who do not work, Java Executor is convenient
argius note: Review of parallel processing and multithreading using Concurrency Utilities
A framework that aims for maximum speed by tuning the Executor framework for work that can be recursively divided into small units. The WorkStealing algorithm is used to speed up the process. Introduced in Java 1.7.
Work Stealing is an algorithm that steals work. Fork a task finely and set it in a queue, and when the worker thread receives a task from the queue, steal the task of another queue if all the tasks in the queue are completed.
ForkJoinPool, which is the core function of the ForkJoin framework, is an implementation class of ExecutorService, and ForkJoinTask is an implementation class of Future. ForkJoinPool implements the WorkStealing algorithm.
ForkJoinTask is an abstract class but does not inherit directly. Implement the task class by inheriting RecursiveAction if it does not return the result, and RecursiveTask if it returns the result. ForkJoinPool calls compute from execute or submit, so implement the process in compute. The result is Future.
As we've seen many times, multithreaded programming often requires you to choose between returning and not returning results. I wasn't sure what the difference was. Is it faster to not return it?
ParallelStream Stream API concurrency that incorporates a functional paradigm. Introduced in Java 1.8.
It is very easy because you can generate a Stream from a set such as Collection and realize parallel processing with one parallel shot. It's easy to do because you can concisely describe functional processing without side effects by implementing it using a functional interface.
Processing that has side effects (changes the state) in parallel processing is taboo, but be aware that Java also has a function interface that has side effects.
However, if fine tuning is required, it seems better to use the Executor framework. In some cases, serial is faster, and just because it's easy doesn't mean that you can make everything parallel. I'm not sure how to use it properly because it's difficult to draw a line.
reference Legend of Java Concurrency/Parallelism -Yuichi Sakuraba
Recommended Posts