Java Multi-Threading

Source: Internet
Author: User

What is a process?

A process is a task in the operating system that is an area of memory that contains some resources. A process can contain one or more execution units called threads, which can be seen as executing at the same time (actually taking CPU resources in turn, switching quickly to seemingly simultaneous execution). Each process also has a private virtual address space that can only be accessed by the included thread. When the operating system creates a process, the process automatically requests a thread called the main thread.

What is a thread?

A thread is a sequence of processes that executes a stream, and a homogeneous thread can share a piece of memory space and a set of system resources. Threads are very small when switching, so threads are also becoming light processes. A process can contain multiple sets of threads.


What is the difference between a process and a thread?

A process has at least one thread, and the thread has a smaller scale than the process. Because each process has a separate unit of memory during execution, the process consumes a lot of resources when switching. While multiple threads share this memory, there is no need to switch the memory unit during the thread switching process, so the operation efficiency is greatly improved. The meaning of multithreading is that in an application, there are multiple execution parts that can be executed concurrently. However, the operating system does not consider these threads as standalone programs for process scheduling and resource allocation.


Concurrency and parallelism?

Multiple threads are executed at the same time, which is only seen on the macro level. The fact is that the OS divides the CPU run time into many time slices, gets the time slice of the thread to execute, and waits for the other threads. Because the switching speed is very fast, so the macro is performed simultaneously, but the microscopic is not, this is called concurrency. Parallel execution is performed at the same time, both micro and macro, where parallel programs can be implemented by multiple CPUs.


Create thread create thread and start thread using thread

Define a specific thread by inheriting the thread class and overriding the Run method in the thread class. The purpose of overriding the Run method is to define the logic that the thread executes. The startup thread is not called the Run method, but instead calls the thread's start () method. The start () method takes a thread into the thread dispatch sequence, which is available for execution after the current thread acquires a time fragment. The thread class is a thread class, and each instance represents a thread that can run concurrently.

Class Samplethread extends thread {public void run () {System.out.println ("Override the Run method by inheriting the thread Class");} public static void Main (string[] args) {samplethread thread = new Samplethread (); Thread.Start ();}}

Create and start a thread using runnable

Implement the Runnable interface and override the Run method to define the thread body, and then create the thread to pass the runnable instance into and start the thread. The benefit of this is to reduce coupling by separating the definition thread from the task that the thread will perform. Also, Java is single-inheritance, and if a class inherits the thread class, it cannot inherit other classes. (The thread class also implements the Runnable interface)

In the Runnable interface, only the abstract run method is defined:

public abstract void run ();

Class Samplethread implements Runnable {public void run () {System.out.println ("overriding the Run method by inheriting the thread Class");} public static void Main (string[] args) {Samplethread sample = new Samplethread (); Thread thread = new thread (sample); Thread.Start ();}}
Create a thread with an anonymous inner class
Thread thread = new Thread () {public void Run () {};};

Break Thread in

The thread terminates when the Run method is executed, or the exception is not caught. However, if you want to force a thread to terminate, you can use the interrupt method to request a terminating thread.

A thread break is a change in the interrupt state of a thread, which may be death after an outage, may be waiting for a new task, or it may proceed to the next step, which depends on the program itself. The thread will constantly detect this interrupt identifier bit to determine if it should be interrupted. However, if the thread is blocked, terminating the thread with interrupt throws a Interruptedexception exception.

Use isinterrupted to detect if a thread is interrupted

Boolean isinterrupted ()

Boolean interrupted (): Tests if the front thread is interrupted, but this call has a side effect, and he sets the current interrupt state to False

void Interrupt (): Send interrupt request, interrupt status is set to True


Thread state

A thread can have a status of 6:

NEW: Newly Created

Runnable: Can be run

Blocked: Blocked

Waiting: Waiting

Timed Waiting: Timed Wait

Terminated: Was terminated

Detecting current thread state through the GetState () method


New Thread creation

Create a thread using the new operator, such as new Thread (t), which has not started running. When a thread is in the newly created state, the description program has not yet run the code in the thread.


Can run threads

Once the start () method is called, the thread is in the runnable state, the thread in the running state may or may not be running, which depends on the operating time provided by the OS. In fact, the interruption is to allow other threads to get running time.


Blocked threads and waiting threads

Blocked threads and waiting threads, they are temporarily inactive, do not run any code and consume the least amount of resources. Until the thread scheduler activates it again.

When a thread attempts to acquire an internal object lock that is held by another thread, the thread goes into a blocking state. When all other threads release the lock, and the scheduler allows the thread to hold him, the thread becomes non-blocking.

When a thread waits for another thread to notify the scheduler of a condition, it enters its own wait state. This behavior occurs if you call the Object.wait method or the Thread.Join method, or wait for lock or condition.


Timing Status

There are several methods that have a timeout parameter that calls them causing the thread to enter a timed state, which will continue until the timeout expires or the appropriate notification is received. Methods with timing Thread.Sleep (), object.wait (), Thread.Join (), Lock.trylock (), condition.await


Terminated thread

There are two reasons for a thread termination:

The Run method exits gracefully and dies naturally.

died unexpectedly because an exception was not caught and the Run method was terminated


Thread Manipulation API
Get thread Information

Thread Thread.CurrentThread () method: Gets the thread that is currently running the code snippet

Thread thread = Thread.CurrentThread ();

Boolean isAlive (): Test thread is active

Boolean Isdaemon (): Test whether the thread is a daemon thread

Boolean isinterrupted (): Test thread has been interrupted

Long GetId (): Gets the thread identifier

String getName (): Returns the thread name

int getpriority (): Return thread Priority

Thread.state getState (): Get thread state


Thread Priority

Thread switching is controlled by thread scheduling, and we cannot interfere with code, but we can improve thread priority to maximize the chance of a thread acquiring a time slice.

Thread priority is divided into 10 levels, of 1-10, of which 1 is the smallest and 10 is the largest. Thread provides three constant values representing the lowest, highest, and default precedence

Thread.min_prioriity

Thread.max_priority

Thread.normal_priority

Set by the SetPriority () method


Daemon Threads

Java threads are divided into two categories: the user thread and the daemon thread (the daemon thread). Daemon threads are handy for running other threads, such as the garbage collector is a daemon thread. Daemon and user thread are not different, the main difference is the departure of the virtual machine: When all user thread exit, only daemon Thread is left, then the virtual machine will be exited. The daemon is not the only virtual machine available, and the user can also set the pass: Setdaemon (Boolean on)

Do not easily set the daemon thread, because you do not know when the user thread is finished, if the user thread after the completion of the daemon thread you defined is not finished, it will also be forced to quit


Sleep () method

The sleep (Long mills) method is to cause the current process to block state, enter the blocking time for the specified number of milliseconds, block the time passed into the runable state, and wait for the time slice to be allocated. This method throws a interruptedexception at the time of declaration, so the exception is caught when using this method.


Yield () method

static void Yield (): voluntarily let go of the time slice back to runnable state, waiting to allocate time slices.


Join () method

Used to wait for the current thread to end, the method throws Interruptedexception.


Thread synchronization

Thread concurrency security issues occur when multiple threads read and write to the same critical resource at the same time. For example, when two threads read the same object, and each thread modifies the state of the object, the error occurs, which is called a race condition.

If you want to solve a thread-safety problem, you need to change the asynchronous operation into a synchronous operation:

Asynchronous operations: Multithreading concurrent operations, each performing their own

Synchronous operations: There are sequential operations that you perform I do not perform


Lock Object

Java provides two mechanisms to prevent code blocks from being interfered by concurrent access, one that is familiar with using the Synchronized keyword, and the other using the Reentrantlock class.


Reentrantlock:

Lock lock = new Reentrantlock (), Lock.lock (), try{//critical section code block, which guarantees that only one thread will enter the critical section at any time, and once a thread has blocked the lock object, no other thread can pass the lock statement// When lock is called, they are blocked until the first thread releases the lock object}finally{lock.unlock ();}

Unlock release lock object must be put in finally, if the critical section code throws an exception, finally can release the lock object, otherwise the other threads will always block.

Each such object has its own reentrantlock () object, and if two threads access the same class object, the serial service is provided. However, when accessing different objects, each thread has a different lock object, and two threads do not clog. Operation of different instances, between threads is unaffected.


Condition Object

Consider that when a thread enters the critical section and discovers that a condition is required to run, he has acquired the lock object, but cannot execute it down, which is solved by the conditional object (the condition variable) in Java.

A lock object can have multiple conditional objects and use the await () method to obtain a conditional object using the Newcondition () method, when it is possible for a condition to be executed (which can be judged to determine whether the condition is met), when the current thread is blocked and the lock is discarded. When another thread finishes executing, the Signalall () method is called when the condition is satisfied so that all threads waiting for one condition are activated.

Lock lock = new Reentrantlock (); Condition Condition = Lock.newcondition ();                 Lock.lock (); try{if                         (//Determine if a condition is satisfied, if not satisfied)                                         conditon.await ();                        //Critical block blocks, which ensures that only one thread enters the critical section at any time, Once a thread has blocked the lock object, no other thread can pass the lock statement//When lock is called, they are blocked until the first thread releases the lock object ...                       After the other threads have finished executing, the current condition may be met, reactivation of                       condition.signalall ();               } Finally{lock.unlock ();}

Using the Synchronized keyword

Declare the method with the Synchronized keyword. An internal lock is provided for each object from Jdk1.0,java, and if a method uses the Synchronized keyword adornment, the object lock will protect the entire method, that is, the thread must obtain an internal lock object to invoke the method. The internal lock object also has a related condition, and the Wait () method adds a thread to the wait set, and the Notify/notofyall method touches the blocking state of the waiting thread.

The wait () method is equivalent to the await () method above, and Notify/notifyall is equivalent to the Signal/signalall method above.

Public synchronized void Method () {if (//Condition State) wait ();    ....    Notifyall ();}

This method of direct locking is required to lock the current method, there is a synchronous blocking.

Synchronized (Sync Monitor-lock object) {            //code block}

Select the appropriate lock object:

Synchronized need to lock an object to ensure thread synchronization, then this object should ensure that when multiple threads need to be synchronized to access the synchronization block, they should see the same lock object, otherwise not achieve the synchronization effect, usually use this as the lock object.


So when do you use the displayed thread lock Lock/unlock, and when to use the Synchronized keyword?

The best case is not to use a mechanism in the java.util.concurrnt package that locks the code you are dealing with. For example, you can use a blocking queue to complete

If you use the Synchronized keyword for your program, use it as much as you can to reduce the amount of code and prevent errors.


Executorservice Implementing a thread pool

Thread pool role: Controlling the number of threads, reusing threads

When a program creates a large number of threads and destroys them at the end of a task, it can cause excessive resource consumption and the risk of switching threads, causing the system to crash and use a thread pool to solve the problem.

Principle: First create some threads, their collections become the thread pool, when the server accepts a request from the client, a free thread is fetched from the thread pool, and the service completes without shutting down the thread and returning to the thread pool. In the online pool programming model, the task is submitted to the thread pool, not to one of the threads, and after the thread pool is taken to the task, there are no idle threads in the inline pools, and the task is given to the idle thread. One thread can perform only one task, but it is possible to submit multiple tasks to the thread pool at the same time.

Implementation method:

1.

Executorservice pool = Executors.newcachedthreadpool ();

Create a thread pool that can create new threads as needed, but reuse them when previously constructed threads are available.

2.

Executorservice pool = Executors.newfixedthreadpool (nthreads);

Create a fixed collection of thread pools that share unbounded queues to run these threads.

3.

Executorservice pool = Executors.newscheduledthreadpool (corepoolsize)

Creates a thread pool that schedules a command to run after a given delay or executes periodically.

4.

Executorservice pool = Executors.newsinglethreadexecutor ();

Create a executor that uses a single work thread to run the thread in an unbounded sequence.
Class Samplethread  {public static void main (string[] args) {Executorservice pool = Executors.newfixedthreadpool (2); Handler Handler = new Handler (); for (int i =0; i<5;i++) {Pool.execute (Handler);}}} Class Handler implements runnable{@Overridepublic void Run () {String name = Thread.CurrentThread (). GetName (); for (int i=0 ; i<10;i++) {System.out.println ("Currently executing thread is:" +name), try {thread.sleep (+);} catch (Interruptedexception e) { E.printstacktrace ();}} SYSTEM.OUT.PRINTLN ("Task execution Complete");}}


Blockingqueue

Blockingqueue is a double-buffered sequence, and we can use query if we need to use a queue when multithreading is concurrent. However, synchronization slows down concurrent operations on query, and you can use Blockingquery.

The Blockingqueue uses two queues internally, allowing two two threads to be stored at the same time in the queue, one for read operations. Improves queue access efficiency while ensuring concurrency security

When Blockingqueue is empty, the thread will be interrupted to wait until Blockingqueue has something, and the thread will be woken up to continue the operation. If the Blockingqueue queue is full and then put something inside, the thread will be interrupted into a wait state until there is room in the blockingqueue until it wakes up and continues.


Throw exception Special values Blocking Timeout
Insert Add (E) Offer (e) Put (e) Offer (E,time,unit)
Removed from Remove () Poll () Take () Poll (Time,unit)
Check Element () Peek () Not available Not available

Add (E): Adds an element to the queue, returns True if Blockingqueue can accommodate, or throws an exception

Offer (E): Adds an element to the queue, returns True if Blockingqueue can hold, otherwise returns false

Put (E): Add an element to the queue, insert if blockingqueue can accommodate, or enter a blocking state if it cannot be inserted until it can be inserted

The following method is the same principle


Four implementation classes for Blockingqueue

Arrayblockingqueue: Specifies the size of the blockingqueue, you need to specify an int parameter to specify its size, containing the objects are in FIFO order.

Linkedblockingqueue: Blockingqueue of variable size, if the constructor specifies a size, it is the blockingqueue queue size, or Integer.max_value size if not specified. The contained objects are sorted in FIFO order.

Priorityblockingqueue: Similar to Linkedblockqueue, but not ordered in FIFO order. Instead, the order in which the comparator is determined depends on the natural order of the object or the constructor.

Synchronousblockingqueue: is a special kind of blockingqueue, the operation needs to be executed alternately.


which Linkedblockingqueue and the Arrayblockingqueue compare them , the data structures behind them are different. , cause Linkedblockingqueue the data throughput to be greater than Arrayblockingqueue, However, when the number of threads is large, its performance is less predictable than Arrayblockingqueue.


Viewing its source code will discover that each operation of the queue is reentrantlock with a lock object.

Test the Offer method if inserting more than two seconds without entering the sequence returns false

blockingqueue<integer> queue = new arrayblockingqueue<integer>, for (int i =0;i<20;i++) {try {Boolean result = Queue.offer (i, 2, timeunit.seconds);//Insert after 2 seconds if not successfully returned FALSESYSTEM.OUT.PRINTLN ("Deposit succeeded:" + result);} catch (Interruptedexception e) {e.printstacktrace ();}}

Test the poll () method and return False if the element is not removed for more than 2 seconds
blockingqueue<integer> queue = new arrayblockingqueue<integer>, for (int i =0;i<10;i++) {Queue.offer (i);} for (int i=0;i<20;i++) {try {Integer result = Queue.poll (2, timeunit.seconds);   If the element is not taken after two seconds, the NULLSYSTEM.OUT.PRINTLN is returned ("Result:" +result);} catch (Interruptedexception e) {e.printstacktrace ();}}




Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Java Multi-Threading

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.