Java concurrency Programming in-depth learning

Source: Internet
Author: User
Tags cas semaphore

Basic concepts

In practice, concurrent programming is chosen in order to make better use of resources to improve the overall throughput of the system. But because of the problems of context switching and deadlock, concurrent programming does not necessarily improve performance, so the focus of this article is how to make reasonable concurrent programming, and then introduce some basic knowledge about locks (choose learning).

  • volatile: lightweight, which guarantees the visibility of shared variables , makes it possible for multiple threads to change shared variables in a timely manner. It consists of two sub-processes that write data from the current processor cache row back to system memory, and then invalidate the data in other CPUs that cache the memory address.
  • synchronized: Relative weight, which consists of 3 forms, for the normal synchronization method, the lock is the current instance object, for the static synchronization method, the lock is the class object of the current classes, and for the synchronization code block, the lock is the object that is configured within synchonize brackets. In addition, the lock used by synchronize exists in the Ava object header, and a similar code is inserted after compilation monitorenter, monitorexit .
  • lock Status: Includes lock-free status, Bias lock status, lightweight lock status, and heavyweight lock status. Tip, the lock can be upgraded but not degraded.
  • Java implements atomic operations : Atomic operations can be achieved by locking and circulating CAs, but there are also 3 problems, including the ABA problem, which is solved by version number, the long overhead of the cycle time, and pause the cost of the spin by the instruction, which can only guarantee the atomic operation of a shared variable. Let's AtomicRefence look at one of the simplest examples of CAS operations by guaranteeing atomicity between referenced objects.

    protected void safeCount() { for (;;) { int i = atomicI.get(); if (atomicI.compareAndSet(i, ++i)) break; }}
Thread

This part and the subsequent lock is the core of the basic part and needs to be well understood. In general, threads are the smallest scheduling unit of the operating system, and one process can contain multiple threads, each with its own counters, stacks, and local variables. The system will dispatch the running thread in the form of ticks, the OS will separate the time slices to the thread, and also set the priority of the thread to ensure that the higher priority thread gets more CPU time. The following sample code shows that the Java program is run not only as a main thread, but also as a clear reference thread, a thread that calls the Finalize method of the object, a thread that distributes the information sent to the JVM, a Attach listener thread, and so on.

 //get admin thread mxbeanthreadmxbean Threadmxbean = managementfactory.getthreadmxbean ();  threadinfo[] Threadinfos = threadmxbean.dumpallthreads (true, true); //print thread information for (threadinfo ThreadInfo : Threadinfos) {system.out. println ( "[" + threadinfo.getthreadid () +  "]" + Threadinfo.getthreadname ());}              
  • Thread State : The entire life cycle of a Java thread consists of 6 different states, the NEW initial state, the thread is built but not start; RUNNABLE Running state, the Java thread is called "Running" in both the ready and running states of the OS, and BLOCKED blocks the state, indicating that the thread is blocking the lock; waiting waiting state, indicating that the thread is in a wait state. Entering this state indicates that the current thread needs to wait for a specific action (notification or interruption) by another thread; time_waiting time-out wait state, which is different from waiting , which returns after the specified time; TERMINATED terminating state, you can use interrupt () to terminate the thread reasonably, indicating that the current thread has finished executing, After that, a Java thread state graph is adopted to make an image. The concept of the

    Daemon daemon thread is simple, and Java's virtual machine exits only if there are no daemon threads.

  • inter-thread communication has a classic paradigm, waiting/notification mechanism . One thread modifies the value of one object, and the other thread perceives the change, and then takes the appropriate action, starting with one thread and finally executing another.

    //等待方:1.获取对象的锁 2.如果条件不满足,那么调用对象的wait方法,被通知后要检查条件//3.条件满足则执行对应的逻辑synchronized(lock){while(!flag){lock.wait();}}//通知方:1.获取对象的锁 2.改变条件 3.通知所有等待在对象上线程synchronized(lock){flag = true;lock.notifyAll();}


    If thread a executes thread.join (), it indicates that thread a waits for a thread to be terminated before returning from Thread.Join (), which also provides a join (long Millis) and join (int millis, int nanos) method, which is forced to return when the predecessor thread has not ended in a given point in time.
    ThreadLocalA thread variable is a ThreadLocal storage structure that takes an object as a key and any object as a value. In addition, this part of the common application example includes waiting time-out mode, database thread pool, simple Web server based on thread pool, etc.

Lock

A lock is a way to control how multiple threads access shared resources, which are handled by the thread synchronization problem before the lock interface appears synchronized . The main methods of locking are,,, lock tryLock unlock newCondition Obtaining methods such as waiting for the notification component. Its related implementations include queue Synchronizer AbstractQueuedSynchronizer , re-entry lock ReentrantLock , read-write lock ReentrantReadWriteLock , Locksupport, and condition interface, which is focused on reentrant lock reenterlock.

  • re-entry ReentrantLock lock Indicates that the lock can support a thread's repeated lock on a resource and support a choice of fairness when it is acquired. The default is a non-fair lock, which is characterized by a much higher performance than a fair lock (which is obtained in strict order of request time, FIFO).

    lock = new ReentrantLock(true);lock.lock();try { // TODO} finally { lock.unlock();}
  • read/ ReentrantReadWriteLock write lock While maintaining a read lock and a write lock, allowing multiple read threads to access shared data at the same time, only blocks when the write thread accesses it, and is similar to the lock mechanism of the database, which makes concurrency wait for a significant increase. In addition to the fairness of the selection, re-entry and other characteristics, but also support the lock downgrade, follow the acquisition of write lock, read lock and then release the order of the write lock, write lock can be downgraded to read lock.
  • Locksupport provides a park unpark static method of blocking, waking.
  • Condition Interface : Any Java object, has a set of monitor methods, including, wait() and notify() so on, these methods and synchronized keyword Mates can implement the wait/notification mode, the Condition interface also provides a similar monitor method, But the functionality is more powerful.

Advanced concepts concurrent containers and frameworks
    • concurrenthashmap VS HashTable: The decision to learn Java concurrency programming, can be said to be interviewed by the interviewer godless to live this problem. It was only known that Concurrenthashmap was a thread-safe version of HashMap, but its differences with Hashtable were never cared for. In short, the former Segment HashEntry is packaged to a record-level lock granularity, similar to database-related knowledge. Hashtable performance is low because only [table] level locks are supported. ConcurrentLinkedQueueis the thread-safe version of the queue, there is nothing special to say.
    • The blockingqueue blocking queue is a queue that supports two additional operations, one that supports blocking inserts, that is, when the queue is full, the queue blocks the thread that inserts the element until the queue is dissatisfied, and the other supports blocking removal methods, meaning that when the queue is empty, The thread that gets the element waits for the queue to become non-empty. They are handled in such a way as to throw exceptions, return special values, keep blocking, and timeout exits. The blocking queues provided by Java7 include, ArrayBlockingQueue LinkedBlockingQueue , and so on DelayQueue , not the focus.
    • fork/join Framework : JAVA7 provides a parallel development framework similar to Map/reduce, where Fork can break down tasks into subtasks, and join is responsible for summarizing the results. It involves a work-stealing work-stealing algorithm that allows threads to steal tasks from other queues, with the advantage of taking advantage of threads for parallel computing and reducing the competition between threads; The disadvantage is that in some cases there is competition, for example, when there is only one task in a double-ended queue, the algorithm consumes more system resources.
Concurrency tool classes

This part of the content is very important, after the introduction of some common patterns can be very good application in the daily development scenarios, must grasp the solid.

  • 13 Atomic Operation Classes : More common Have and, AtomicBoolean AtomicInteger AtomicIntegerArray , AutomicReference etc., next choose a more complex as an example.

    new User("xionger", 30);atomicUserRef.set(user);User updateUser = new User("xiongerda", 32);atomicUserRef.compareAndSet(user, updateUser);System.out.println(atomicUserRef.get().getName());System.out.println(atomicUserRef.get().getOld());
  • Countdownlatch: Similar to a counter that allows one or more threads to wait for other threads to complete operations, such as the main thread that waits for 2 child threads to complete a task and return. Common scenarios, such as our parsing of Excel multiple sheet data, can be processed by each thread one, and then the completion of the notification system after the completion of the resolution.

    static Countdownlatch latch =New Countdownlatch (3);Publicstatic void main  (string[] args) throws interruptedexception {new Thread (new Runnable () { @Override public void run< Span class= "Hljs-params" > () {Latch.countdown ();}}). Start (); new Thread (new Runnable () {@ Override public void run () {Latch.countdown ();}}). Start (); Latch.await ();}                
  • cyclicbarrier: It allows a set of threads to reach a barrier, similar to the starting line of a run, until the last thread reaches the barrier, the barrier opens, and all blocked threads continue to execute. In order to be used for multi-threaded computing data, the final consolidation of data scenarios, such as the use of an Excel to save the user all bank water, each sheet save an account for nearly a year of water, now to count the daily average water, then you can calculate the daily flow of each sheet, the final summary. The use CountDownLatch is similar to some, but it is characterized by the ability to use reset method resets and to isBroken() determine if a thread is interrupted.
  • The Semaphore semaphore is used to control the number of threads concurrently accessing a particular resource, often with traffic control, such as the control of a database connection, with 50 threads that require a 15 database connection.

    Privatestatic Executorservice Executorservice = Executors.newfixedthreadpool (50);Privatestatic Semaphore sema =New Semaphore (15);public static void main (string[] args) { for (int i = 0; i < 50; i++) {Executorservice.execute (new Runnable () {@Override Span class= "Hljs-keyword" >public void run ( try {sema.acquire (); System. out.println ( "save Data"); Sema.release ();} catch (interruptedexception e) {e.printstacktrace ();}} }); } executorservice.shutdown (); } 
  • The Exchanger exchanger can be used for inter-thread data exchange, which provides a synchronization point at which two threads can exchange data from each other. Exchange can be used in genetic algorithms and proofing work and other scenarios, such as the need to input the paper into the system, in order to avoid dislocation, using AB Gang two people input, entered into Excel, the system needs to load the two Excel and proofread.

    PrivateStaticFinal exchanger<string> Exchanger =New Exchanger<> ();Privatestatic Executorservice ThreadPool = Executors.newfixedthreadpool (2);PublicStaticvoidMain(string[] args) {Threadpool.execute (New Runnable () {@OverridePublicvoidrun () {String a =  "bank pipelining a"; try {exchanger.exchange (a);} catch (interruptedexception e) {e.printstacktrace ();}} }); Threadpool.execute (new Runnable () { @Override public void run< Span class= "Hljs-params" > () {String b =  "bank pipelining B"; try {String a = Exchanger.exchange (b); System.out.println ( "A and B are data consistent:" + a.equals (b) + catch (interruptedexception e) {e.printstacktrace ();}});     
Executor frame
    • thread Pool
      Before introducing the executor framework, this paper introduces the principle of thread pool, which is the most important part of concurrent programming, the reasonable use of thread pool can reduce system consumption, improve the response speed and improve the manageability of threads, then introduce the basic processing flow of thread pool.

      1. If the currently running thread is less than corepoolsize directly creating a new thread to perform the task, the global lock needs to be acquired.
      2. If the thread that is running equals or is redundant corepoolsize the task into Blockingqueue.
      3. If the task cannot be added to Blockingqueue because the queue is full, a new thread task is created and a global lock needs to be acquired.
      4. If you create a new thread that will operate maximumpoolsize, the task is rejected and the Rejectedexecutionhandler.rejectedexecution () method is called.
      Threadpoolexecutor uses the above steps to ensure the executionexecute(), you avoid getting a global lock as much as possible, and most of the time you may be doing step 2 without acquiring a global lock.
      Before introducing the executor framework, the Java thread is both a working unit and an execution mechanism. And inExecutor Frame, the unit of work and the execution mechanism are separated, the former includesRunnableAndCallable, and the implementation mechanism is provided by the executor framework. The framework is a two-level scheduling model in which multiple tasks are mapped to a fixed number of threads through the scheduler executor, and at the bottom, the operating system kernel maps these threads to the processor. Our application simply controls the upper-level dispatch via the E-frame.
      TIP:
      Inreasonable allocation of thread pool, the corresponding solution needs to be given according to the specific scenario, in general, the use of bounded queues is recommended for easy control.
      CPU-intensive: Configure as few threads ascpu数量+1, you can passRuntime.getRuntime().availableProcessors()Get the number of CPUs
      IO-intensive: Configure as many threads as possible, such as2*cpu数量, a common scenario that waits for the return of a database or service interface.
      Priority: You can passPriorityBlockingQueueTo handle
      Monitoring: Available throughtaskCount,completedTaskCount,getActiveSizeand other functions to monitor the running of the thread pool.

    • Executor frame structure mainly consists of three parts
      A. Tasks, including the interface of task implementation Runnable andCallable
      B. Implementation of the task, including the core interface of the task execution mechanism Executor and its subclasses ExecutorService , related implementation classes include ThreadPoolExecutor and ScheduledThreadPoolExecutor .
      C. The results of asynchronous computations, including Future and their implementation FutureTask .
    • threadpoolexecutor: The core class of the framework, consisting of,,, corePool maximumPool BlockingQueue RejectedExecutionHandler 4 parts, can be created by the tool class Executors . In particular, the tool class can create FixedThreadPool a fixed number of threads (most recommended), SingleThreadExecutor and CachedThreadPool three types ThreadPoolExecutor .
    • Scheduledthreadpoolexecutor: More comprehensive than the underlying Timer object, which is passed DelayQueue to perform periodic or timed tasks.
    • Futuretask based on Abstractqueuedsynchronizer (AQS), previously described in Reentrantlock , The Countdownlatch is actually based on Aqs. AQS is a synchronization framework that provides a common mechanism to atomically manage synchronization states, Block & wake threads, and maintain blocked thread queues. Each AQS-based implementation contains two types of operations, acquire for blocking the calling thread, corresponding to futuretask.get () , knowing that the AQS state allows the thread to continue execution, and the other for release, corresponding to the Futuretask.cancel () &run () , which alters the AQS state, allowing one or more blocking threads to unblock.

       public  Static void main (String[] args) Span class= "Hljs-keyword" >throws interruptedexception, executionexception {Executorservice executor = Executors.newsinglethreadexecutor (); future<bigdecimal> result = Executor.submit (new callable<bigdecimal> () { Span class= "Hljs-meta" > @Override public BigDecimal call () throws Exception {return getsalarybyservice (); } }); System.out.println (Result.get ());}             
    • producer Consumer Mode : This mode solves most of the concurrency problems by blocking the queue, balancing the production line and consuming threads ' ability to improve the overall processing speed of the program. For example, often e-mail to share technical knowledge, you can get the article through the job to the mailbox and put into the blocking queue, then the consumer to obtain data and insert into a similar Confluence document management tool, the next show a single producer, multiple consumers of the application scenario implementation.
      TIP:
      On-line problem targeting: You can view the progress top of a process through commands in Linux, and then you can use interactive commands to view 1 CPU performance and H view performance information for each thread.
      Performance testing: For example, using JMeter for pressure measurement, you can netstat -nat | grep 3306 -c check the pressure of the data.

Java concurrency Programming in-depth learning

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.