The main content index of this article
1. Java Threads
2. Threading Model
3. Java thread pool
4. Future (various future)
5. Fork/join Frame
6. Volatile
7. CAS (Atomic operations)
8, AQS (concurrent synchronization framework)
9, synchronized (synchronous lock)
10. Concurrent queue (blocking queue)
This article only analyzes some of the core problems in Java concurrency programming, and the technology that is not mentioned above but is closely related to Java concurrent programming will be added to improve the article, this article will be long-term update, continuous iteration. This article attempts to summarize the concurrency programming content in the Java language from a higher vision, hopefully after reading this article, you should know what to pay attention to when doing concurrency programming in Java, what to focus on, how to ensure thread safety, and how to choose the right tools to meet your needs. Of course, the deeper content will be related to the JVM level of knowledge, including the bottom of the Java Memory Management, threading management and other core issues, of course, the positioning of this article is abstract and summary, more specific and in-depth content needs to practice, considering that may be too long, repeated description of some content, and the depth of their own technology, this article will make some tradeoffs in depth and breadth, some content will do some in-depth analysis, and some content will be around, donuts, in short, this article is to learn Java concurrent programming content of a summary, And for those who want to quickly understand the Java concurrent programming content of the reader, the shortcomings of the point of view.
One, Java threads
In general, the implementation of high concurrency in Java is based on multithreaded programming, so-called concurrency, that is, multiple threads working at the same time to deal with our business, in the machine universal multi-core today, the significance of concurrent programming is very significant, because we have multiple CPUs for thread use, If our application still uses only single-threaded mode to work, it is extremely wasteful of machine resources. So, the first problem with learning Java concurrency is: how do you create a thread and let the thread do something? This is the starting point for Java concurrent programming content, which describes several ways to create threads and let threads do something.
Inherit the thread class
Inherit the thread class, and then override the Run method, which is the first method to create a thread. The Run method is what we want to do, in the Run method to write the task we want to run in the new thread, here is a small example, we inherited the thread class, and in the Run method to print out the name of the thread of course, and then sleep1 seconds after the exit:
/*** Created by hujian06 on 2017/10/31.** the demo of Thread*/public class Threaddemo {public static void main (String: . args) {Athread athread = new Athread ();//start the thread Athread.start ();}} Class Athread extends Thread {@Override public void run () {System.out.println ("Current Thread Name:" + thread.currentthr EAD (). GetName ()); try {thread.sleep;} catch (Interruptedexception e) {e.printstacktrace ();}}}
If we want to start this thread, just like in the code above, call the Start method of the thread class.
Implementing the Runnable Interface
The second way to start a thread is to implement the Runnable interface, and then implement its run method, write the business code you want to execute inside the new thread in the Run method, and the following example shows an example of how to start the thread, the same functionality as the first example above:
/*** Created by hujian06 on 2017/10/31.** the demo of Runnable*/public class Arunnableademo {public static void main (Stri Ng ... args) {Arunnanle Arunnanle = new Arunnanle (); Thread thread = new Thread (ARUNNANLE); Thread.Start (); }}class Arunnanle implements Runnable {@Override public void run () {System.out.println ("Current Thread Name:" + thread.c Urrentthread (). GetName ()); try {thread.sleep;} catch (Interruptedexception e) {e.printstacktrace ();}}}
At the start of the thread, we still use the thread class, but we passed the Runnable object we implemented in the constructor, so when we execute the start method of the thread class, the actual execution is our runnable run method.
Using Futuretask
The third way to start a new thread is to use Futuretask and take a look at Futuretask's class diagram to see why you can use Futuretask to start a new thread:
The
Futuretask class diagram
Shows from the Futuretask class diagram that Futuretask implements the Runnable interface and the future interface. So it has runnable and future two features, let's take a look at how to use Futuretask to start a new thread:
import Java.util.concurrent.callable;import Java.util.concurrent.executionexception;import java.util.concurrent.futuretask;/*** Created by hujian06 on 2017/10/ 31.** the demo of Futuretask*/public class Futuretaskdemo {public static void main (String ... args) {acallable callable = new Acallable (); futuretask<string> futuretask = new futuretask<> (callable); Thread thread = new Thread (futuretask); Thread.Start (); do {}while (!futuretask.isdone ()); try {String result = Futuretask.get (); SYSTEM.OUT.PRINTLN ("Result:" + result);} catch (Interruptedexception | Executionexception e) {e.printstacktrace ();}}} Class Acallable implements callable<string> {@Override public String call () throws Exception {thread.sleep (1000); Return "Thread-name:" + thread.currentthread (). GetName ();}}
As you can see, after using Futuretask to start a thread, we can monitor whether the thread is complete, the main thread in the example above will wait for the newly created thread until it returns, in fact, as long as the future provides the interface, we can use in the Futuretask, This greatly facilitates us, the future in the meaning of concurrent programming is extremely important, the futures represent a thing that will happen in the coming, it is a hint, a placeholder, it signals that we may not get the result immediately, because its task is still running, but we can get a monitor object to this thread , we can make some judgments about the execution of threads, or even control, for example, if we think we've waited too long, and we don't feel the need to wait any longer, we can cancel the task, and one thing to mention is that the future represents that it may be running, or it may have returned, Of course, the future implies that you can wait for the result and use other threads to do something else, and when you really need it, it's time to get it, which is concurrency, and it's important to understand that.
This section introduces three ways to create and start a new thread, to open a header for concurrent programming, and for now, we are only able to create multiple threads, and then let multiple threads do different things, of course, this is the most fundamental to learning concurrent programming, anyway, now, We can get our app to run multiple threads, and the following article will discuss some of the interesting aspects of concurrent programming based on this hypothesis, where multiple threads are opened by an application. For more detailed information about this section, you can refer to some of the articles in Java completablefuture.
Second, threading model
We can now start multiple threads, but it doesn't seem like a model-like thing, it's confusing, and so far our multiple threads are just doing their own thing, interacting with each other, with no interaction (communication) between multiple threads, which is the simplest model and the most basic model, This section attempts to introduce threading models, a concept that guides our code organization, a threading model that determines the problems that we need to deal with multithreading, which is unlikely in a system where there is no communication between multiple threads, and more generally, multiple threads share some resources and compete against each other for resource permissions. Multiple threads work together to improve the processing power of the system. Because there is a communication interaction between multiple threads, the next discussion in this article makes sense, and if there are hundreds of threads in our system that are working, but these threads are irrelevant, then such a system would either be very single or meaningless (certainly not absolute, such as Netty's threading model).
Continue to discuss the threading model, which refers to the threading model is a kind of guidance code organization IDEA, this is my own understanding, different threading model requires us to use different code organization, good threading model can improve the concurrency of the system, and can make the complexity of the system is reduced, here need to mention Netty 4 threading model, Netty 4 threading model makes it easy to understand Netty's event handling mechanism, this excellent design is based on reactor threading model, reactor threading model is divided into single-threaded model, multithreaded model and master-slave multithreaded model, The threading model of Netty is similar to the reactor master-slave multithreaded model.
Of course, the threading model is a higher level of concurrent programming content, which is a programming guideline, especially when we are designing the underlying framework, especially when we need to pay attention to the threading model, because once the threading model is not properly designed, it can cause the later framework code to be too complex, and may cause problems due to thread synchronization problems are not controllable, Eventually the system runs out of control. The threading model similar to Netty is a good threading model, and the following shows this model:
Netty Threading Model
Simply, Netty assigns a nioeventloop to each newly established channel, and each nioeventloop uses only one thread internally, which avoids the synchronization problem of multithreading concurrency, because there is only one thread for each channel processing, So do not need to use the lock thread synchronization means to do thread synchronization, in our system design should draw on this threading model design ideas, can avoid us to go a lot of detours. For the thread pool and Netty thread pool This part of the content, you can refer to the article Netty threading model and EventLoop detailed. Java thread pool Pooling is a very useful technique, and for threads, the cost of creating a thread is very high, and if we are going to recycle it after creating a thread and having the thread do a task, we need to create a new thread the next time we use the thread to perform our task. Is it possible to buffer until a thread has been created and then recycle it when the system shuts down? Java thread pool is such a component, using the thread pool, there is no need to create threads frequently, the thread pool will manage threads for us, when we need a new thread to perform our task, we request to the thread pool, and the thread pool will find an idle thread from the pool to return to the requestor, If there are no threads available in the pool, the thread pool creates a new thread based on some parameter metrics, or submits our task to the task queue, waiting for an idle thread to perform the task. The details are analyzed below, so for now we just need to understand that there are a lot of threads in the thread pool that will continue until the system relationship is recycled, otherwise it will always be in the state of the processing task or waiting for the task to be processed. First, how do you use the thread pool? The following code shows an example of how to use the Java thread pool:
Import Java.util.concurrent.executorservice;import Java.util.concurrent.executors;import Java.util.concurrent.scheduledexecutorservice;import Java.util.concurrent.threadfactory;import Java.util.concurrent.timeunit;import java.util.concurrent.atomic.atomicinteger;/*** Created by hujian06 on 2017/10/ 31.** the demo of Executors*/public class Executorsdemo {public static void main (String ... args) {int cpucorecount = Ru Ntime.getruntime (). Availableprocessors (); Athreadfactory threadfactory = new Athreadfactory (); Arunnanle Runnanle = new Arunnanle (); Executorservice fixedthreadpool= Executors.newfixedthreadpool (Cpucorecount, threadfactory); Executorservice Cachedthreadpool = Executors.newcachedthreadpool (threadfactory); Scheduledexecutorservice Newscheduledthreadpool = Executors.newscheduledthreadpool (CpuCoreCount, threadFactory); Scheduledexecutorservice singlethreadexecutor = Executors.newsinglethreadscheduledexecutor (threadFactory); Fixedthreadpool.submit (Runnanle); Cachedthreadpool.suBmit (Runnanle); Newscheduledthreadpool.scheduleatfixedrate (Runnanle, 0, 1, timeunit.seconds); Singlethreadexecutor.schedulewithfixeddelay (Runnanle, 0, timeunit.milliseconds); try {TimeUnit.SECONDS.sleep (5);} catch (Interruptedexception e) {e.printstacktrace ();} fixedthreadpool.shutdownnow () ; Cachedthreadpool.shutdownnow (); Newscheduledthreadpool.shutdownnow (); Singlethreadexecutor.shutdownnow (); }}class Arunnable implements Runnable {@Override public void run () {try {thread.sleep ()} catch (interruptedexcept Ion e) {e.printstacktrace ();} System.out.println ("Current Thread Name:" + thread.currentthread (). GetName ());}} /*** the thread Factory*/class Athreadfactory implements Threadfactory {private final Atomicinteger threadnumber = new at Omicinteger (1); @Override public Thread Newthread (Runnable r) {return new Thread ("athread-" + threadnumber.incrementandget ());}}
Richer applications should be explored on their own, combined with their own needs to use the thread pool to achieve, the following analysis of Java thread pool implementation of a few more important content.
Threadpoolexecutor and Scheduledthreadpoolexecutor
Threadpoolexecutor and Scheduledthreadpoolexecutor are the core classes of Java implementation thread pools, and different types of thread pools are actually using different constructors. and different parameters to construct Threadpoolexecutor or scheduledthreadpoolexecutor, so the focus of learning the Java thread pool is also to learn the two core classes. The former is suitable for constructing the general thread pool, while the latter inherits the former, and many contents are universal, but Scheduledthreadpoolexecutor adds the schedule function, that is, The scheduledthreadpoolexecutor is used to construct a thread pool with scheduling functions and can use Scheduledthreadpoolexecutor in scenarios where periodic dispatch execution is required. For more in-depth analysis of threadpoolexecutor and Scheduledthreadpoolexecutor, you can refer to the following article:
Java thread pool details (ii) Java thread pool detailed (a) Java dispatch thread pool Scheduleexecutorservicejava dispatch thread pool Scheduleexecutorservice (cont.)
How difficult is Java concurrent programming? Have you mastered these core technologies?