Java Concurrency Basics

Source: Internet
Author: User
Tags semaphore thread class

I. BASIC threading mechanism

Concurrent programming allows us to divide the program into separate, separate, running tasks. These separate tasks can be driven by the execution thread by using multithreading mechanisms. A thread is a single sequential control flow in a process.

1. Create a thread

1.1 Implement the Runnable interface and implement the Run method.

The traditional way to convert a Runnable object into a work task is to give it to the thread constructor.

Thread t = new Thread (new Runnable ());

T.start ();

1.2 Inherit the thread class and override the Run method.

1.3 Executor

The executor (Executor) in the Java.util.concurrent package in Java SE5 is used to manage thread objects, and Executor allows you to manage the execution of asynchronous tasks. Executor is the preferred way to start a task.

Executorservice exec = Executor.newcachedthreadpool ();

Executorservice exec = Executor.newfixedthreadpool (5);//Use limited thread set processing tasks.

Executorservice exec = Executor.newsinglethreadpool ();//Like a fixedthreadpool with a thread count of 1. If you submit multiple tasks to Singlethreadpool, These tasks are queued for execution.

Exec.execute (New Runnable ());//Perform Tasks

Exec.shutdown ();//can prevent new tasks from being submitted to executor.

1.4 Generating return values from tasks

Runnable is a standalone task that performs work, but it does not return a value. If you want the task to return a value, you need to implement the callable interface to implement the call method. Callable is a generic with type parameters.

Exec.submit (New callable ());//submit () will produce a future object, which is parameterized with the results returned by callable. The future object can return an object without waiting for the result, and when the result is needed, Obtained using the Future.get () method. You can also use Iddone () to determine whether the processing thread ends before getting the result of the processing.

1.5 Sleep

An easy way to keep a thread in a blocking state is to call the sleep () method. The Timeunit class is introduced in Java SE5 to specify a time unit for sleep.

When you call sleep, you throw interruptedexception, the exception cannot propagate across threads, so the exceptions in the thread are handled inside the task.

The await () method also causes the thread to be blocked, and the main difference between it and sleep is that the await releases the lock, but sleep does not. An await is usually used in coordination between threads.

1.6 Priority level

The priority of threads can be set in Java. However, the priority of the thread does not guarantee that the priority thread will be executed first. High-priority threads have a greater advantage over the time of the cup. In most of the time, all threads should run with the default thread priority, and attempting to change the thread priority is an error.

The JDK has 10 priorities, but it is not very well mapped to most operating systems. The priority of the portable can be max-priority,min-priority,nrom-priority

1.7 Concessions

The static method of thread yied () causes the current thread to discard the time slice of the cup, allowing all ready-state threads (including itself) to re-rob the cup time slice. Calling the Yied method is equivalent to telling the current thread: Your work is almost done and you can get other threads to work.

1.8 Background Threads

A background thread, also known as a daemon thread, is a thread that provides generic services in the background while the program is running, and that thread is not an integral part of the program. When all non-background threads end, the program terminates, and all background threads are killed. A GC in Java is a background thread.

Setting a thread to a background thread can call the T.setdaemon () method when the thread starts. It is important to note that all threads derived by the background thread are default to the background thread, and we can pass the T.isdaemon () To determine whether a thread is a background thread. The finally statement block in a background thread is not guaranteed to execute, because when all non-background threads have finished executing, the JVM shuts down all background threads immediately and exits. Finally, the JVM exits and is forcibly interrupted.

1.9 Adding a thread

If a thread T calls T.join () on another thread A, the thread will be suspended until the T thread ends, or a timeout parameter can be taken in the join method. Calls to the join () method can be interrupted and calls to the interrupt () method on the calling thread .

Two shared restricted resources

1. Sharing resources 2. Changes are involved 3. Multiple threads using

Basically, all concurrency patterns are used to serialize access to shared resources when resolving thread-conflict problems-that is, only one thread is allowed to access the shared resource at the same time.

2.1 Plus lock mechanism

Synchronized

Using the displayed lock object

In Java SE5, there is a lock mutex in the Java.util.concurrent package. The lock object must be displayed to create, lock, and release. Lock is more flexible than synchronied. For example, in synchronied, there is an exception. Only one exception can be thrown, but in the lock object, the failed cleanup work is handled in finally and the lock is released. The Synchronied keyword cannot attempt to acquire a lock and eventually get a failure, or try to get a period of time and then discard it , to implement these, you must use the Concurrent class library.

Private Reentrantlock lock = new Reentrantlock ();

Boolean captured = Lock.trylock (2,timeunit.secinds);

try{}

finally{

if (captured) {

Lock.unlock ();

}

}

2.2 Atomicity and variability

An atomic operation is an operation that cannot be interrupted by a thread-scheduling mechanism, and once the operation is started, it must be executed before the context switch occurs. Relying on atomicity to solve concurrency problems is tricky and dangerous. Expert programmers can use atomicity to write lock-free code, but it's too hard.

Atomicity can be applied to all basic types except long and double. Long and double use two 32-bit memory that you can store and manipulate, and in concurrent threads you may see a condition that reads only a high of 32 or a low of 32.

Volatitle keywords can ensure visibility in your app.

2.3 End Task

There must be a reasonable finalization method for the running tasks so that they can properly terminate and process the resource release operations after the finalization. Sometimes you have to end a task that is in a blocking state.

Possible reasons for entering the blocking state:

1. Call the Hibernate method by thought.

2. The thread is suspended by calling wait.

3. The task waits for IO input or output to complete.

4. The task waits for a lock on an object.

Several ways to break

The 1.Thread class contains the interrupt () method, which sets the interrupt state of the thread. If a thread has been blocked or a blocking operation is performed, setting this interrupt state throws interruptexception.

2. The new concurrent class library seems to be avoiding direct manipulation of the thread object, and instead tries to do all of the work through executor. Shoutdownnow () is available in executor To interrupt all threads that are started by the current executor. When you need to break only one thread, you can start the thread by executor the Submit () method, and then break the thread by Cance;l (true).

You can interrupt sleep-caused blocking, but you cannot interrupt a thread that attempts to acquire a synchronied lock or attempt to perform an IO operation. Typically, you want to interrupt such a thread by shutting down the underlying resource to achieve the interrupt.

A feature added to the Java SE5 Concurrency Class library is that a task that is blocked on Reentrantlock has the ability to be interrupted, which is completely different from the task of blocking on the Synchronied method or the critical section.

In a task loop, the interrupt state is usually used to check if the task is interrupted and then it is rolled out. By setting the interrupt state of a task and not immediately interrupting the program, an exception is thrown only when the task is in or attempting to enter a blocking state.

Collaboration between three threads

Collaboration between threads allows multiple tasks to work together to solve a problem.

3.1 Wait () and Notifyall ()

Wait () causes the thread to hang, waiting for a condition to occur, usually this condition is not controlled by the current thread, and the current thread is changed and awakened by another thread. The fundamental difference between the wait () method and sleep () is that the wait method releases the lock, and the call to wait () must be in a synchronous code block Because wait has to operate the lock.

The wait () method has two ways, the first of which is to accept a number of milliseconds as an argument. You can recover from the Wait method by notify (), Notifyall (), or time expires. The second is to not accept parameters, only by Notify, Notifyall method to wake.

Wait, Notify,notifyall are all methods of object. Not part of the thread class. These three methods can also be called only in synchronous or synchronous blocks, because an operation lock is required. If they are called in non-synchronous code, Compilation can be done by running a illegalmonitorstateexception exception and will be accompanied by some vague messages, such as the current thread is not the owner.

Notify Notifyall is the thread that wakes the current lock, notify is the one that wakes up, and the notifyall is all that wakes up.

Usually when waking all threads with Notifyall, all the awakened threads first have to check if they are the condition of their own concern, and if they do not continue to wait, this will ensure that the program executes correctly. Because if there are multiple tasks waiting for the same lock, when these tasks are simultaneously awakened, The first task might modify the condition, and then the other tasks should continue waiting for the wait condition. That is, use the while to write the code for the Wait section, ensuring that the code is executed in the correct condition.

Notify and Notifyall

Notify is an optimization of notifyall, but when using notify, it is necessary to ensure that the appropriate task is awakened. Otherwise, use Nofityall.

Condition Object

The condition object is the base class in the concurrent package that allows tasks to be suspended, a task can be suspended by an await (), using signal (), Signalall () Awaken the task on this condition. It's safer to use Notifyall without using Signalall.

3.2 Synchronization Queue

Using wait and notifyall in a very low-level way to accomplish the collaborative problem between tasks, which is to shake hands every time. In a very good case, you can choose to use a higher level of abstraction, Use synchronization queues to complete collaboration issues. The synchronization queue allows only one task to insert or remove an element at any time. This queue is provided in the Concurrent.blockingqueue interface, This interface has a large number of implementations. There are no queue linkedblockingqueue and there is a queue arrayblockingqueue. When the queue is empty, you can suspend a task that attempts to get elements from the queue. These tasks can be awakened when there are elements in the queue. Blocking queues can solve a lot of problems, simpler and more reliable than using wait and notifyall.

3.3 Between tasks by using pipelines for input/output

The Java class Library corresponds to the PipedWriter and Pipedreader classes, and this model looks like a producer-consumer variant. The pipeline is basically a blocking queue. First create a PipedWriter object, The Pipedreader object that is associated with this pepedwriter is then passed in to the PipedWriter object in the Pipedreader constructor. When the Pepedreader object is called by the Reade () method, If there is no data in the pipeline into the blocking state.

3.4 Dead Lock

Conditions for deadlocks:

1. There are mutually exclusive conditions.

2. At least one task holds the lock on one resource and then gets another resource that is held by other tasks.

3. Resources cannot be preempted by tasks.

4. Cycle wait.

A deadlock can only be resolved by breaking any one of the deadlock conditions.

The components in the four-new class library

4.1 Countdownlatch

It is used to synchronize one or more tasks, forcing them to wait for a set of operations performed by another task to complete.

Sets an initial value for the Countdownlatch object, and any task that calls the wait () method on the object will block until the count reaches 0. Other tasks can call Countdown () on the object when execution is complete method to reduce the value of this count. Note that Countdownlath can only be triggered once and the value of the meter cannot be reset.

4.2 Cyclicbarrier

Use this scenario: you want to build a set of tasks, they perform the work in parallel, and then wait until all tasks are completed before proceeding to the next step. It allows all tasks to be lined up at the fence so that they can move forward in a consistent way. Cyclicbarrier is a bit like countidownlatch, but Cyclicbarrier can be reused many times.

4.3 delayqueue

This is an blockingqueue that is used to place an object that implements the delayed interface. objects can only be removed from the queue when they expire. This kind of queue is ordered, that is, the delay time of the object is the longest. If there are no deferred objects, then there will be no header element, and poll () will return null (because of this, you cannot put NULL in this queue).

There is a method Getdelay () in the Delayedtask interface that can be used to tell how long the delay expires, or how long the delay has expired.

The order of execution of tasks in the Delayqueue queue is independent of the Order of creation, and is only related to the delay time of the task.

4.4 Priorityblockingqueue

This is a priority queue that has a blocking read operation. This queue is a task that appears in priority order from the queue, and the priority is defined by a priority number.

4.6 Scheduledexecutor

Set the Runnable object to be executed at a later time by using schedule () (run once) or Scheduleatfixedrate (), which repeats the task at intervals.

4.6 Semaphore

The normal lock allows only one task to be accessible at any given time, while the count semaphore allows n tasks to access the resource simultaneously, you can view the number of semaphores as a license to distribute the use of resources out of the hand, although no license objects are actually used.

4.7 Exchanger

Excheger is a fence between two tasks that swap objects. When these tasks enter the fence, they each have an object, and when they leave, they have each other's object. Typical application scenario for exchanger: One task is creating objects, these objects are expensive to produce, and another task is consuming these objects, and exchanger can have more objects to be consumed immediately after creation.

Java Concurrency Basics

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.