preface
What if the limit really exists? So where is it? All right, don’t pretend ~.
JAVA concurrency related knowledge system, can be said to be learned over and over again, each time um…… Let’s do it systematically again. Let’s start with, how many ways to implement multithreading? This time I say two!!
The website says there are two
First look at the Oracle website document description (https://docs.oracle.com/javase/8/docs/api/index.html)
Because the website says there are only two ways to implement multithreading, so I’m going to say there are two
- Method 1: Inherit Thread
- Method 2: Implement the Runable interface
There are several kinds of folk?
So the question is, right? There are a lot of articles on the web that say you can use Callable, FutureTask, thread pool, and multithreading. Is this true?
I can only say that the statement is not accurate, that can only source interpretation of a wave, one by one, not urgent ~
FutureTask, Callable
First of all, FutureTask and Callable can actually create a new thread. Let’s take a look at the class inheritance diagram for FutureTask
From the class inheritance diagram, FutureTask also implements the Runable interface and can pass Callable type parameters in the constructor. So essentially, the way to do multithreading with FutureTask is through the Runable interface.
Thread pool
Have a look at the thread pool to create methods: ExecutorService ExecutorService = Executors. NewFixedThreadPool (1);
Take a look at the newFixedThreadPool(1) method
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
Copy the code
Through the layers of calls, the class that produces the Thread is DefaultThreadFactory, essentially the Thread created by calling new Thread(). So Thread pools implement multithreading essentially through the Thread class
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private finalString namePrefix; DefaultThreadFactory() { SecurityManager s = System.getSecurityManager(); group = (s ! =null)? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix ="pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if(t.getPriority() ! = Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY);returnt; }}Copy the code
The official website has two ways which way is better
The Runable implementation is a little better
- Implement the Runable interface to create less thread loss. Since inheriting a Thread class with a new Thread each time and subsequent destruction is costly, implementing the Runable interface can reuse a Thread to perform tasks, and Thread pools do the same by passing in the Runable interface as an argument.
- JAVA does not support multiple inheritance, which makes extensibility feel poor
- The Thread class also maintains a Runable property, and the run() method is also the Runable method called. We just inherited Thread and overrode the run() method. So it’s essentially using the Runable interface.
conclusion
- In essence, there are only two ways to implement multithreading. If the implementation is implemented through inheritance and wrapping, then there are so many ways to implement multithreading in the JDK, including wrapping, inheriting the Thread class and Runable interface.
- The more you know, the more you don’t know.
Welcome to scan code attention
If you like, please pay attention to my public number [program listener] and tell your story! I am here to listen! Text address