As we all know, before JDK1.5, Java in the business concurrency, often need to have the programmer to complete the code implementation, of course, there are some open source framework to provide these features, but these still do not have the functionality of the JDK is easy to use. When it comes to high quality Java multithreaded concurrent programming, in order to prevent the phenomenon such as dead jump, such as wait (), notify () and synchronized before using Java, often need to consider performance, deadlock, fairness, Many factors, such as resource management and how to avoid the harm caused by thread security, often adopt some more complicated security policies, which aggravate the development burden of programmers. Luckily, after JDK1.5, Sun great God (Doug LEA) finally launched the Java.util.concurrent Toolkit for our poor little programmers to simplify concurrency. Developers use this to effectively reduce competitive conditions (race conditions) and deadlock threads. The concurrent package solves these problems well and provides us with a more practical model of concurrent programs.
Executor: The performer of a specific runnable task.
Executorservice: A thread pool manager with a variety of implementation classes, I'll introduce a section. We can submit the runnable,callable to the pool for scheduling.
Semaphore: a count signal quantity
Reentrantlock: A reentrant mutex lock that functions like a synchronized, but much more powerful.
Future: is an interface that interacts with runnable,callable, such as the result of a thread being returned after execution, and the cancel termination thread is also provided.
Blockingqueue: Blocking queues.
Completionservice:executorservice extension that can get the result of the thread execution
Countdownlatch: A synchronization helper class that allows one or more threads to wait all the time before completing a set of operations that are being performed in another thread.
Cyclicbarrier: A synchronization helper class that allows a set of threads to wait on each other until a common barrier point is reached
Future:future represents the result of an asynchronous computation.
Scheduledexecutorservice: A executorservice that can schedule commands to run or execute periodically after a given delay.
The next step is to introduce
Executors Main Method Description
Newfixedthreadpool (fixed size thread pool)
Create a thread pool of reusable fixed-thread collections to run these threads in a shared, unbounded queue (which, if requested, waits for execution in a queue). If any thread terminates due to failure during execution prior to shutdown, a new thread will perform the subsequent task (if needed) instead.
Newcachedthreadpool (no boundary pool, can be automated thread collection)
Create a thread pool that can create new threads as needed, but reuse them when previously constructed threads are available. These thread pools generally improve program performance for programs that perform many short-term asynchronous tasks. Calling execute reuses the previously constructed thread (if the thread is available). If an existing thread is not available, create a new thread and add it to the pool. Terminates and removes threads from the cache that have not been used for 60 seconds. Therefore, a thread pool that remains idle for a long time does not use any resources. Note that you can use the Threadpoolexecutor construct method to create a pool of threads with similar properties but with different details, such as time-out parameters.
Newsinglethreadexecutor (single background thread)
Create a Executor that uses a single worker thread to run the thread in a unbounded queue. (Note that if this individual thread is terminated because of a failure during execution prior to shutdown, a new thread will perform the successor task if needed). Each task is guaranteed to be performed sequentially, and no multiple threads are active at any given time. Unlike other equivalent Newfixedthreadpool (1), it is guaranteed that other threads can be used without reconfiguring the execution program returned by this method.
These methods return the Executorservice object, which can be understood to be a thread pool.
The function of this thread pool is still quite perfect. You can submit task submit () to end the thread pool shutdown ().
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;
public class Myexecutor extends Thread {
private int index;
Public myexecutor (int i) {
this.index=i
}
public void Run () {
try{
System.out.println ("[+this.index+"] start ... ");
Thread.Sleep ((int) (Math.random () *));
System.out.println ("[" +this.index+ "] end.");
}
catch (Exception e) {
e.printstacktrace ();
}
}
public static void Main (String args[]) {
executorservice service=executors.newfixedthreadpool ();
for (int i=;i<;i++) {
service.execute (new Myexecutor (i));
Service.submit (New Myexecutor (i));
}
System.out.println ("Submit Finish");
Service.shutdown ();
}
Although some of the information is printed, but it's not very clear how this thread pool works, we're going to increase the sleep time by 10 times times.
Thread.Sleep ((int) (Math.random () *10000));
Again, it will be clear to see that only 4 threads can be executed. When a thread is executed, a new thread is executed, that is, after we commit all the threads, the thread pool waits for the last shutdown to execute. We will also find that the submitted thread is placed in a "unbounded queue". This is an ordered queue (Blockingqueue, which will be mentioned below).
In addition, it uses the static function of executors to generate a fixed thread pool, as the name suggests, thread pool threads are not released, even if it is idle.
This creates performance problems, such as if the thread pool size is 200, all threads will continue to remain in the pool when all is used, and the corresponding memory and thread switching (while (true) +sleep loops) will increase.
If you want to avoid this problem, you must use Threadpoolexecutor () directly to construct it. You can set the maximum number of threads, the minimum number of threads, and the idle thread keepalive time as the common thread pool.
This is the basic usage of the thread pool.
Semaphore
A number of counting signals. Conceptually, the semaphore maintains a collection of permissions. If necessary, each acquire () is blocked before the license is available, and then the license is obtained. Each release () adds a license that may free a blocking user. However, without using the actual license object, semaphore only counts the number of available licenses and takes action accordingly.
Semaphore is typically used to limit the number of threads that can access certain resources (physical or logical). For example, the following class uses semaphores to control access to a content pool:
Here is a practical situation, everyone in line to the toilet, the toilet only two locations, 10 people need to queue.
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;
Import Java.util.concurrent.Semaphore; public class Mysemaphore extends Thread {semaphore position; private int id; public mysemaphore (int i,semaphore s) {thi
S.id=i;
This.position=s;
public void Run () {try{if (position.availablepermits () >) {System.out.println ("Customer [" +this.id+] Enter the toilet, there is a vacancy ");
else{System.out.println ("Customer [" +this.id+ "] into the toilet, no vacancy, queue");
} position.acquire ();
System.out.println ("Customer [" +this.id+ "] obtain pit position");
Thread.Sleep ((int) (Math.random () *));
System.out.println ("Customer [" +this.id+ "] use complete");
Position.release ();
catch (Exception e) {e.printstacktrace ();
} public static void Main (String args[]) {executorservice list=executors.newcachedthreadpool ();
Semaphore position=new Semaphore ();
for (int i=;i<;i++) {list.submit (new Mysemaphore (i+,position));
} list.shutdown ();
Position.acquireuninterruptibly ();
SYSTEM.OUT.PRINTLN ("Use completed, need to clean up");Position.release (); }
}
Reentrantlock
A reentrant mutex lock that has the same basic behavior and semantics as the implicit monitor accessed using the Synchronized method and statement, but is more powerful.
The reentrantlock will be locked by the most recent success and is not owned by the thread that released the lock. When a lock is not owned by another thread, the thread that calls lock succeeds in acquiring the lock and returning it. If the current thread already owns the lock, this method returns immediately. You can use the Isheldbycurrentthread () and Getholdcount () methods to check whether this condition occurs.
The constructor method of this class accepts an optional fair parameter.
When set to true, in contention for multiple threads, these locks tend to grant access to the thread with the longest waiting time. Otherwise, this lock will not guarantee any particular access order.
Programs that use fair locking have a very low overall throughput (that is, slow, often extremely slow) when many threads access, compared to the default (use of unfair locking), but are less significant when locking is secured and the balance of lock allocations is guaranteed.
However, it should be noted that fair locking does not guarantee the fairness of thread scheduling. As a result, a member of a large number of threads using a fair lock can gain multiple chances of success, which occurs when other active threads are not processed and are not currently holding locks.
Also note that the Trylock method does not use fair settings. This method can succeed, even if other threads are waiting, as long as the lock is available.
The recommendation is always to practice immediately, using a try block to invoke lock, and in the previous/subsequent constructs the most typical code is as follows:
Class X {
private final reentrantlock lock = new Reentrantlock ();
// ...
public void M () {
lock.lock ();//block until condition holds
try {
//... method body
} finally {
loc K.unlock ()}}}
My example:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;
Import Java.util.concurrent.locks.ReentrantLock; public class Myreentrantlock extends thread{testreentrantlock lock, private int id; public myreentrantlock (int i,testreen
Trantlock test) {this.id=i;
This.lock=test; public void Run () {Lock.print (ID),} public static void Main (String args[]) {Executorservice SERVICE=EXECUTORS.NEWCA
Chedthreadpool ();
Testreentrantlock lock=new Testreentrantlock ();
for (int i=;i<;i++) {service.submit (new Myreentrantlock (I,lock));
} service.shutdown (); Class testreentrantlock{Private Reentrantlock lock=new reentrantlock (); public void print (int str) {try{Lock.lo
CK ();
System.out.println (str+ "obtained");
Thread.Sleep ((int) (Math.random () *));
catch (Exception e) {e.printstacktrace ();
} finally{System.out.println (str+ "release");
Lock.unlock (); }
}
}
Blockingqueue
A queue that supports two additional operations: waiting for the queue to become non-null when the element is retrieved, and waiting for space to become available when the element is stored.
Blockingqueue does not accept null elements. When attempting to add, put, or offer a null element, some implementations throw nullpointerexception. Null is used as a warning value to indicate the failure of the poll operation.
Blockingqueue can be of limited capacity. It can have a remainingcapacity at any given time, exceeding this capacity, and cannot put extra elements without blocking.
Blockingqueue that do not have any internal capacity constraints always report the remaining capacity of the integer.max_value.
The Blockingqueue implementation is primarily used for producer-consumer queues, but it also supports Collection interfaces. Therefore, for example, it is possible to remove any element from the queue using remove (x).
However, such operations are usually not performed effectively and can only be used occasionally, for example, when the queued information is canceled.
The Blockingqueue implementation is thread-safe. All queuing methods can automatically achieve their purpose by using internal locking or other forms of concurrency control.
However, a large number of Collection operations (AddAll, Containsall, Retainall, and RemoveAll) do not need to be performed automatically unless specifically described in the implementation.
Thus, for example, AddAll (c) may fail (throw an exception) after adding only some elements in C.
Blockingqueue essentially does not support the use of any "close" or "shutdown" action to indicate that no item is added.
The need for and use of this functionality has a tendency to rely on implementation. For example, a common strategy is to insert special end-of-stream or poison objects for the producer and interpret them based on the time that the user gets those objects.
The following example illustrates the basic functionality of this blocking queue.
Import Java.util.concurrent.BlockingQueue;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;
Import Java.util.concurrent.LinkedBlockingQueue; public class Myblockingqueue extends Thread {public static blockingqueue<string> queue = new Linkedblockingqueue< ;
String> ();
private int index;
The public myblockingqueue (int i) {this.index = i} is public void run () {try {queue.put (string.valueof (This.index)); System.out.println ("{" + This.index + "} in queue!");}
catch (Exception e) {e.printstacktrace ();
} public static void Main (String args[]) {Executorservice service = Executors.newcachedthreadpool ();
for (int i =; I < i++) {Service.submit (new Myblockingqueue (i)); Thread thread = new Thread () {public void run () {try {while (true) {thread.sleep (int) (Math.random ()
* ));
if (MyBlockingQueue.queue.isEmpty ()) break;
String str = MyBlockingQueue.queue.take (); SYSTEM.OUT.PRINTLN (str + " Has take! ");}}
catch (Exception e) {e.printstacktrace ();
}
}
};
Service.submit (thread);
Service.shutdown (); }
}
---------------------Execution Results-----------------
{0} in queue!
{1} in queue!
{2} in queue!
{3} in queue!
0 has take!
{4} in queue!
1 has take!
{6} in queue!
2 has take!
{7} in queue!
3 has take!
{8} in queue!
4 has take!
{5} in queue!
6 has take!
{9} in queue!
7 has take!
8 has take!
5 has take!
9 has take!
-----------------------------------------
Completionservice
A service that separates the production of new asynchronous tasks from the results of using completed tasks. The tasks performed by producer submit. The consumer take the completed tasks and processes their results in the order that they were completed. For example, Completionservice can be used to manage asynchronous IO, tasks that perform a read operation are submitted as part of a program or system, and then, when the read operation is completed, other actions are performed in different parts of the program, and the Order of operations may be different from the order in which they are requested.
Typically, Completionservice relies on a single Executor to actually perform a task, in which case Completionservice only manages an internal completion queue. The Executorcompletionservice class provides an implementation of this method.
Import java.util.concurrent.Callable;
Import Java.util.concurrent.CompletionService;
Import Java.util.concurrent.ExecutorCompletionService;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;
public class Mycompletionservice implements callable<string> {private int id; public mycompletionservice (int i) {
This.id=i;
public static void Main (string[] args) throws exception{Executorservice Service=executors.newcachedthreadpool ();
completionservice<string> completion=new executorcompletionservice<string> (service);
for (int i=;i<;i++) {completion.submit (new Mycompletionservice (i));
for (int i=;i<;i++) {System.out.println (Completion.take (). get ());
} service.shutdown ();
Public String Call () throws Exception {Integer time= (int) (Math.random () *);
try{System.out.println (this.id+ "start");
Thread.Sleep (time);
System.out.println (this.id+ "End");
catch (Exception e) {e.printstacktrace (); } returnThis.id+ ":" +time;}}
Countdownlatch
A synchronization helper class that allows one or more threads to wait all the time before completing a set of operations that are being performed in another thread.
Initializes the countdownlatch with the given count. Because the countdown () method is invoked, the await method remains blocked until the current count reaches 0.
After that, all waiting threads are freed and all subsequent calls to the await are returned immediately. This phenomenon occurs only once--the count cannot be reset. If you need to reset the count, consider using Cyclicbarrier.
Countdownlatch is a general-purpose synchronization tool that has many uses. The countdownlatch that is initialized with Count 1 is used as a simple open/Guan, or Portal: All threads calling await are waiting at the entrance until the entry is opened by a thread that calls Countdown ().
Countdownlatch initialized with n can cause a thread to wait until N threads complete an operation, or to wait until an operation completes N.
A useful feature of Countdownlatch is that it does not require the thread that calls the countdown method to wait until the count arrives 0 o'clock, and until all threads pass, it simply blocks any thread from continuing through a await.
The example is written by someone else, very image.
import Java.util.concurrent.CountDownLatch; import
Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors; public class Testcountdownlatch {public static void main (string[] args) throws Interruptedexception {//Start Countdown Lock final
Countdownlatch begin = New Countdownlatch ();
The final countdownlatch end = new Countdownlatch () of the ending Countdown lock;
10 finalists Final Executorservice exec = Executors.newfixedthreadpool ();
for (int index =; index < index++) {final int NO = index +; Runnable run = new Runnable () {public void run () {try {begin.await ();//Block Thread.Sleep (long) (Math.ran
Dom () *));
System.out.println ("No." + No + "arrived");
catch (Interruptedexception e) {} finally {End.countdown ();
}
}
};
Exec.submit (run);
} System.out.println ("Game Start");
Begin.countdown ();
End.await ();
System.out.println ("Game over");
Exec.shutdown (); }
}
The most important method of Countdownlatch is Countdown () and await (), the former is mainly the penultimate, the latter is waiting for the countdown to 0, if not reached 0, only blocking wait.
Cyclicbarrier
A synchronization helper class that allows a set of threads to wait on each other until it reaches a public barrier point (common barrier).
In programs that involve a set of fixed-size threads, these threads have to wait for each other at times, and Cyclicbarrier is useful at this time. Because the barrier can be reused after releasing the wait thread, it is called the barrier of the loop.
Cyclicbarrier supports an optional Runnable command, which runs only once at each barrier point, after the last thread in a set of threads arrives (but before all threads are freed). This barrier operation is useful if the shared state is updated before continuing all participating threads.
Example usage: Here is an example of using barrier in parallel decomposition design, a classic tour example:
Import Java.text.SimpleDateFormat;
Import Java.util.Date;
Import java.util.concurrent.BrokenBarrierException;
Import Java.util.concurrent.CyclicBarrier;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors; public class Testcyclicbarrier {//time required for trekking: Shenzhen, Guangzhou, Shaoguan, Changsha, Wuhan private static int[] Timewal
K = {,,,,};
Self-driving tour private static int[] Timeself = {,,,,};
Tourist bus private static int[] Timebus = {,,,,};
Static String Now () {SimpleDateFormat SDF = new SimpleDateFormat ("HH:mm:ss");
Return Sdf.format (New Date ()) + ":";
Static Class Tour implements Runnable {private int[] times;
Private Cyclicbarrier barrier;
Private String Tourname;
Public Tour (cyclicbarrier barrier, String tourname, int[] times) {this.times = times;
This.tourname = Tourname;
This.barrier = barrier;
public void Run () {try {thread.sleep (times[] *); System.out.println (now () + Tourname + "reached Shenzhen");
Barrier.await ();
Thread.Sleep (times[] *);
System.out.println (now () + Tourname + "reached Guangzhou");
Barrier.await ();
Thread.Sleep (times[] *);
System.out.println (now () + Tourname + "reached Shaoguan");
Barrier.await ();
Thread.Sleep (times[] *);
System.out.println (now () + Tourname + "reached Changsha");
Barrier.await ();
Thread.Sleep (times[] *);
System.out.println (now () + Tourname + "reached Wuhan");
Barrier.await (); The catch (Interruptedexception e) {} catch (Brokenbarrierexception e) {}}} public static void Main (string[
] args {//three tours Cyclicbarrier barrier = new Cyclicbarrier ();
Executorservice exec = Executors.newfixedthreadpool ();
Exec.submit (new Tour (barrier, "Walktour", Timewalk));
Exec.submit (new Tour (barrier, "Selftour", timeself));
When we annotate the following code, we find that the program is blocked and cannot continue to run.
Exec.submit (new Tour (barrier, "Bustour", Timebus));
Exec.shutdown ();
}}
The most important attribute of Cyclicbarrier is the number of participants, and the best method is await (). When all threads have called await (), they indicate that the threads can continue to execute, or they will wait.
Future
Future represents the result of an asynchronous computation. It provides a way to check whether the calculation is complete, to wait for the calculation to complete, and to retrieve the results of the calculation.
Only the Get method can be used to retrieve the results after the calculation is complete, and if necessary, block this method before the calculation completes. Cancellation is performed by the Cancel method.
Other methods are provided to determine whether the task was completed normally or was canceled. Once the calculation is complete, the calculation can no longer be canceled.
If you use Future for the sake of cancellation but do not provide the available results, you can declare the Future<?> form type and return null as the result of the underlying task.
This we've seen in front of completionservice, this future function, and this can be specified as a return object when the thread is submitted.
Scheduledexecutorservice
A executorservice that can schedule commands to run or execute periodically after a given delay.
The schedule method creates a task with various delays and returns a task object that can be used to cancel or check execution. The Scheduleatfixedrate and Schedulewithfixeddelay methods Create and perform certain tasks that run regularly before they are canceled.
The orders submitted using the Executor.execute (java.lang.Runnable) and Executorservice submit methods are arranged by the requested 0 delay.
The schedule method allows 0 and negative numbers to be delayed (but not cycles) and treats these as a request for immediate execution.
All schedule methods accept relative latency and cycles as arguments, rather than absolute time or date. It is easy to convert the absolute time represented by date to the required form.
For example, to schedule a later date, you can use: Schedule (Task, Date.gettime ()-System.currenttimemillis (), timeunit.milliseconds).
Note, however, that because of network time synchronization protocols, clock drift, or other factors, the expiration date of the relative delay does not have to match the current date of the enabled task.
The Executors class provides a convenient factory method for the Scheduledexecutorservice implementation provided in the package.
The example is also more popular on the internet.
import static java.util.concurrent.TimeUnit.SECONDS; import java.util.Date; import
Java.util.concurrent.Executors;
Import Java.util.concurrent.ScheduledExecutorService;
Import Java.util.concurrent.ScheduledFuture; public class Testscheduledthread {public static void main (string[] args) {final Scheduledexecutorservice scheduler = E
Xecutors.newscheduledthreadpool ();
Final Runnable beeper = new Runnable () {int count =;
public void Run () {System.out.println (new Date () + "beep" + (++count));
}
};
After the second run, and run every second final scheduledfuture Beeperhandle = Scheduler.scheduleatfixedrate (Beeper,,, SECONDS); Run after the second, and rerun final scheduledfuture beeperhandle = Scheduler.schedulewithfixeddelay (Beeper,,, SECONDS, after the last task has been run for seconds)
);
The second completes the shutdown task and closes scheduler Scheduler.schedule (new Runnable () {public void run () {Beeperhandle.cancel (true);
Beeperhandle.cancel (TRUE);
Scheduler.shutdown ();
},, SECONDS); }
}
So we have summed up the more important functions under the concurrent package, and hope to help us understand.