1. Java Concurrency from docs.oracle.com
Computer users take it for granted that their systems can do more than one thing at a time. They assume that they can continue to work in a word processor, while other applications download files, manage the print queue, and stream audio. Even a single application is often expected to do more than one thing at a time. For example, that streaming audio application must simultaneously read the digital audio off the network, decompress it, manage playback, and update its display. Even the word processor should always be ready to respond to keyboard and mouse events, no matter how busy it is reformatting text or updating the display. Software that can do such things is known as concurrent software.
The Java platform is designed from the ground up to support concurrent programming, with basic concurrency support in the Java programming language and the Java class libraries. Since version 5.0, the Java platform has also included high-level concurrency APIs. This lesson introduces the platform's basic concurrency support and summarizes some of the high-level APIs in the
In concurrent programming, there are two basic units of execution: processes and threads.
In the Java programming language, concurrent programming is mostly
concerned with threads. However, processes are also important.
Computer users take it for granted that their systems can do more than one thing at a time. They assume that they can continue to work in a word processor, while other applications download files, manage the print queue, and stream audio. Even a single application is often expected to do more than one thing at a time. For example, that streaming audio application must simultaneously read the digital audio off the network, decompress it, manage playback, and update its display. Even the word processor should always be ready to respond to keyboard and mouse events, no matter how busy it is reformatting text or updating the display. Software that can do such things is known as concurrent software.
The Java platform is designed from the ground up to support concurrent programming, with basic concurrency support in the Java programming language and the Java class libraries. Since version 5.0, the Java platform has also included high-level concurrency APIs. This lesson introduces the platform's basic concurrency support and summarizes some of the high-level APIs in the
java.util.concurrent
packages.Processes and Threads
A computer system normally has many active processes and threads.
This is true even in systems that only have a single execution core, and
thus only have one thread actually executing at any given moment.
Processing time for a single core is shared among processes and threads
through an OS feature called time slicing.
It's becoming more and more common for computer systems to have multiple processors or processors with multiple execution cores. This greatly enhances a system's capacity for concurrent execution of processes and threads — but concurrency is possible even on simple systems, without multiple processors or execution cores.
Processes are often seen as synonymous with programs or applications. However, what the user sees as a single application may in fact be a set of cooperating processes. To facilitate communication between processes, most operating systems support Inter Process Communication (IPC) resources, such as pipes and sockets. IPC is used not just for communication between processes on the same system, but processes on different systems.
Most implementations of the Java virtual machine run as a single process. A Java application can create additional processes using a
Threads exist within a process — every process has at least one. Threads share the process's resources, including memory and open files. This makes for efficient, but potentially problematic, communication.
Multithreaded execution is an essential feature of the Java platform. Every application has at least one thread — or several, if you count "system" threads that do things like memory management and signal handling. But from the application programmer's point of view, you start with just one thread, called the main thread. This thread has the ability to create additional threads, as we'll demonstrate in the next section.
It's becoming more and more common for computer systems to have multiple processors or processors with multiple execution cores. This greatly enhances a system's capacity for concurrent execution of processes and threads — but concurrency is possible even on simple systems, without multiple processors or execution cores.
Processes
A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space.Processes are often seen as synonymous with programs or applications. However, what the user sees as a single application may in fact be a set of cooperating processes. To facilitate communication between processes, most operating systems support Inter Process Communication (IPC) resources, such as pipes and sockets. IPC is used not just for communication between processes on the same system, but processes on different systems.
Most implementations of the Java virtual machine run as a single process. A Java application can create additional processes using a
ProcessBuilder
object. Multiprocess applications are beyond the scope of this lesson.Threads
Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process.Threads exist within a process — every process has at least one. Threads share the process's resources, including memory and open files. This makes for efficient, but potentially problematic, communication.
Multithreaded execution is an essential feature of the Java platform. Every application has at least one thread — or several, if you count "system" threads that do things like memory management and signal handling. But from the application programmer's point of view, you start with just one thread, called the main thread. This thread has the ability to create additional threads, as we'll demonstrate in the next section.
Thread Objects
Each thread is associated with an instance of the class
In all of the previous examples, there's a close connection between the task being done by a new thread, as defined by its
Thread
. There are two basic strategies for using Thread
objects to create a concurrent application.- To directly control thread creation and management, simply instantiate
Thread
each time the application needs to initiate an asynchronous task (implements Runnable or SubclassThread
). - To abstract thread management from the rest of your application, pass the application's tasks to an executor.
Thread
objects. Executors are discussed with other high-level concurrency objects.Executors
Runnable
object, and the thread itself, as defined by a Thread
object. This works well for small applications, but in large-scale
applications, it makes sense to separate thread management and creation
from the rest of the application. Objects that encapsulate these
functions are known as executors. The following subsections describe executors in detail.- Executor Interfaces define the three executor object types.
- Thread Pools are the most common kind of executor implementation.
- Fork/Join is a framework (new in JDK 7) for taking advantage of multiple processors.
The
The
with
The
Here is a simple Java
Second, an anonymous implementation of the
Here is a diagram illustrating a thread delegating a task to an
Once the thread has delegated the task to the
ExecutorService Implementations
Since
Creating an ExecutorService
How you create an
ExecutorService Usage
There are a few different ways to delegate tasks for execution to an
- execute(Runnable)
The
- submit(Runnable)
The
Here is a
- submit(Callable)
The
The
- invokeAny()
The
If one of the tasks complete (or throws an exception), the rest of the
Here is a code example:
- invokeAll()
The
Keep in mind that a task might finish due to an exception, so it may not have "succeeded". There is no way on a
Here is a code example:
When you are done using the
For instance, if your application is started via a
To terminate the threads inside the
If you want to shut down the
Reference documents
Java Concurrency in Depth (Part 1)
Java Concurrency in Depth (Part 2)
Java Concurrency in Depth (Part 3)
Java Concurrency in Depth (Part 4)
Java Concurrency in Depth (Part 5)
Java Concurrency in Depth (Part 6)
Java Concurrency in Depth (Part 7)
java-multithreading-concurrency-interview
Java Concurrency Concepts
Java concurrency (multi-threading) - Tutorial
java.util.concurrent
package defines three executor interfaces:Executor
, a simple interface that supports launching new tasks.ExecutorService
, a subinterface ofExecutor
, which adds features that help manage the lifecycle, both of the individual tasks and of the executor itself.ScheduledExecutorService
, a subinterface ofExecutorService
, supports future and/or periodic execution of tasks.
The
Executor
interface provides a single method, execute
, designed to be a drop-in replacement for a common thread-creation idiom. If r
is a Runnable
object, and e
is an Executor
object you can replace(new Thread(r)).start();
e.execute(r);
2. ExecutorService
by Jakob Jenkov from jenkov.comThe
java.util.concurrent.ExecutorService
interface represents an asynchronous execution mechanism
which is capable of executing tasks in the background. An ExecutorService
is thus very similar
to a thread pool. In fact, the implementation of
ExecutorService
present in the java.util.concurrent
package is a thread pool
implementation.Here is a simple Java
ExectorService
example:
ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.execute(new Runnable() { public void run() { System.out.println("Asynchronous task"); } }); executorService.shutdown();First an
ExecutorService
is created using the newFixedThreadPool()
factory method. This creates a thread pool with 10 threads executing tasks.
Second, an anonymous implementation of the
Runnable
interface is passed
to the execute()
method. This causes the Runnable
to be executed
by one of the threads in the ExecutorService
.Here is a diagram illustrating a thread delegating a task to an
ExecutorService
for asynchronous execution:
A thread delegating a task to an ExecutorService for asynchronous execution.
Once the thread has delegated the task to the
ExecutorService
, the thread continues its own execution
independent of the execution of that task.
ExecutorService Implementations
Since
ExecutorService
is an interface, you need to its implementations in order
to make any use of it. The ExecutorService
has the following implementation in the java.util.concurrent
package:
Creating an ExecutorService
How you create an
ExecutorService
depends on the implementation you use. However, you can
use the Executors
factory class to create ExecutorService
instances too.
Here are a few examples of creating an ExecutorService
:
ExecutorService executorService1 = Executors.newSingleThreadExecutor(); ExecutorService executorService2 = Executors.newFixedThreadPool(10); ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
ExecutorService Usage
There are a few different ways to delegate tasks for execution to an
ExecutorService
:
- execute(Runnable)
- submit(Runnable)
- submit(Callable)
- invokeAny(...)
- invokeAll(...)
- execute(Runnable)
The
execute(Runnable)
method takes a java.lang.Runnable
object, and executes it
asynchronously. Here is an example of executing a Runnable
with an ExecutorService
:
ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { public void run() { System.out.println("Asynchronous task"); } }); executorService.shutdown();There is no way of obtaining the result of the executed
Runnable
, if necessary. You will have to use
a Callable
for that (explained in the following sections).
- submit(Runnable)
The
submit(Runnable)
method also takes a Runnable
implementation, but returns
a Future
object. This Future
object can be used to check if the Runnable
as finished executing.
Here is a
ExecutorService
submit()
example:
Future future = executorService.submit(new Runnable() { public void run() { System.out.println("Asynchronous task"); } }); future.get(); //returns null if the task has finished correctly.
- submit(Callable)
The
submit(Callable)
method is similar to the submit(Runnable)
method except
for the type of parameter it takes. The Callable
instance is very similar to a Runnable
except that its call()
method can return a result. The Runnable.run()
method cannot
return a result.
The
Callable
's result can be obtained via the Future
object returned by the
submit(Callable)
method. Here is an ExecutorService
Callable
example:
Future future = executorService.submit(new Callable(){ public Object call() throws Exception { System.out.println("Asynchronous Callable"); return "Callable Result"; } }); System.out.println("future.get() = " + future.get());The above code example will output this:
Asynchronous Callable future.get() = Callable Result
- invokeAny()
The
invokeAny()
method takes a collection of Callable
objects, or subinterfaces
of Callable
. Invoking this method does not return a Future
, but returns the
result of one of the Callable
objects. You have no guarantee about which of the Callable
's
results you get. Just one of the ones that finish.
If one of the tasks complete (or throws an exception), the rest of the
Callable
's are cancelled.
Here is a code example:
ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<Callable<String>> callables = new HashSet<Callable<String>>(); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 1"; } }); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 2"; } }); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 3"; } }); String result = executorService.invokeAny(callables); System.out.println("result = " + result); executorService.shutdown();This code example will print out the object returned by one of the
Callable
's in the
given collection. I have tried running it a few times, and the result changes. Sometimes it is
"Task 1", sometimes "Task 2" etc.
- invokeAll()
The
invokeAll()
method invokes all of the Callable
objects you pass to
it in the collection passed as parameter. The invokeAll()
returns a list of Future
objects via which you can obtain the results of the executions of each Callable
.
Keep in mind that a task might finish due to an exception, so it may not have "succeeded". There is no way on a
Future
to tell the difference.
Here is a code example:
ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<Callable<String>> callables = new HashSet<Callable<String>>(); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 1"; } }); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 2"; } }); callables.add(new Callable<String>() { public String call() throws Exception { return "Task 3"; } }); List<Future<String>> futures = executorService.invokeAll(callables); for(Future<String> future : futures){ System.out.println("future.get = " + future.get()); } executorService.shutdown();ExecutorService Shutdown
When you are done using the
ExecutorService
you should shut it down, so the threads
do not keep running.
For instance, if your application is started via a
main()
method
and your main thread exits your application, the application will keep running if you have an
active ExexutorService
in your application. The active threads inside this ExecutorService
prevents the JVM from shutting down.
To terminate the threads inside the
ExecutorService
you call its shutdown()
method.
The ExecutorService
will not shut down immediately, but it will no longer accept new tasks, and
once all threads have finished current tasks, the ExecutorService
shuts down. All tasks submitted
to the ExecutorService
before shutdown()
is called, are executed.
If you want to shut down the
ExecutorService
immediately, you can call the shutdownNow()
method. This will attempt to stop all executing tasks right away, and skips all submitted but non-processed tasks.
There are no guarantees given about the executing tasks. Perhaps they stop, perhaps the execute until the end.
It is a best effort attempt. 3. Java ExecutorService Example – Tutorial
by Katerina Zamani - javacodegeeks.com
In this example we are going to see some basic functionalities of
myThread.java:
package com.javacodegeeks.core.concurrency.executorservicetest;
public class MyThread implements Runnable {
private String myName;
private int count;
private final long timeSleep;
MyThread(String name, int newcount, long newtimeSleep) {
this.myName = name;
this.count = newcount;
this.timeSleep = newtimeSleep;
}
@Override
public void run() {
// TODO Auto-generated method stub
int sum = 0;
for (int i = 1; i <= this.count; i++) {
sum = sum + i;
}
System.out.println(myName + " thread has sum = " + sum +
" and is going to sleep for " + timeSleep);
try {
Thread.sleep(this.timeSleep);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The functionality of the
The
To close down the
For further understanding of the main functionality of
ExecutorServiceTest.java:
Now you can see the output of the execution.
Output:
ExecutorService
is an interface that extends Executor
class and represents an asynchronous execution. It provides us mechanisms to manage the end and detect progress of the asynchronous tasks.In this example we are going to see some basic functionalities of
ExecutorService
, as well as handle the Future
object, the result of asynchronous computation.3.1. Create the Runnable
We are going to create aRunnable
that is intended to be executed by the ExecutorService
. Create a java class named myThread
and paste the following code.myThread.java:
package com.javacodegeeks.core.concurrency.executorservicetest;
public class MyThread implements Runnable {
private String myName;
private int count;
private final long timeSleep;
MyThread(String name, int newcount, long newtimeSleep) {
this.myName = name;
this.count = newcount;
this.timeSleep = newtimeSleep;
}
@Override
public void run() {
// TODO Auto-generated method stub
int sum = 0;
for (int i = 1; i <= this.count; i++) {
sum = sum + i;
}
System.out.println(myName + " thread has sum = " + sum +
" and is going to sleep for " + timeSleep);
try {
Thread.sleep(this.timeSleep);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Runnable
is very simple. It computes a sum from the giving argument and it sleeps for a specified time.3.2. Code the ExecutorService
In this example we will use a factor method ofExecutorService
that creates a thread pool of fixed number of threads. For this reason, newFixedThreadPool()
method is used where we specify the number of threads in the pool. To execute the thread, we can use either execute()
method or submit()
, where both of them take Runnable
as a parameter. execute()
method is depending on the implementation of the Executor
class and may perform the Runnable
in a new thread, in a pooled thread, or in the calling thread. submit()
method extends execute()
, by returning a Future
that represents the submitting task.The
Future
can be used to indicate the termination of execution of the thread. For instance, get()
method waits for the completion of the computation. If the returning
value is null, the task has finished correctly. Otherwise, cancel()
method can be called in order to end the execution of this task. It is
worth to mention that for bulk or a collection of thread execution, invokeAll()
and invokeAny()
are used respectively, although there are not used in this example.To close down the
ExecutorService
, there are many methods that can be used. In our example we use shutdown()
method, in which the submitted tasks are executed before the shutting
down but new tasks can not be accepted. Another approach is shutdownNow()
method, which stops the executing tasks, pause the waiting ones and returns the list of the awaiting ones. Moreover, awaitTermination()
can be used in order to wait until all threads are terminated.For further understanding of the main functionality of
ExecutorService
, have a look at the code below. Create ExecutorServiceTest.java
file and paste the following.ExecutorServiceTest.java:
package com.javacodegeeks.core.concurrency.executorservicetest;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class ExecutorServiceTest {
private static Future taskTwo = null;
private static Future taskThree = null;
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(2);
// execute the Runnable
Runnable taskOne = new MyThread("TaskOne", 2, 100);
executor.execute(taskOne);
for(int i = 0; i < 2; i++) {
// if this task is not created or is canceled or is completed
if ((taskTwo == null) || (taskTwo.isDone()) || (taskTwo.isCancelled())) {
// submit a task and return a Future
taskTwo = executor.submit(new MyThread("TaskTwo", 4, 200));
}
if ((taskThree == null) || (taskThree.isDone()) || (taskThree.isCancelled())) {
taskThree = executor.submit(new MyThread("TaskThree", 5, 100));
}
// if null the task has finished
if(taskTwo.get() == null) {
System.out.println(i+1 + ") TaskTwo terminated successfully");
} else {
// if it doesn't finished, cancel it
taskTwo.cancel(true);
}
if(taskThree.get() == null) {
System.out.println(i+1 + ") TaskThree terminated successfully");
} else {
taskThree.cancel(true);
}
}
executor.shutdown();
System.out.println("-----------------------");
// wait until all tasks are finished
executor.awaitTermination(1, TimeUnit.SECONDS);
System.out.println("All tasks are finished!");
}
}
Output:
TaskOne thread has sum = 3 and is going to sleep for 100
TaskTwo thread has sum = 10 and is going to sleep for 200
TaskThree thread has sum = 15 and is going to sleep for 100
1) TaskTwo terminated successfully
1) TaskThree terminated successfully
TaskTwo thread has sum = 10 and is going to sleep for 200
TaskThree thread has sum = 15 and is going to sleep for 100
2) TaskTwo terminated successfully
2) TaskThree terminated successfully
-----------------------
All tasks are finished!
Download the source code
This was an example of ExecutorService in Java. Download the source code of this example: ExecutorServiceTest.zip or ExecutorServiceTest.zipReference documents
Java Concurrency in Depth (Part 1)
Java Concurrency in Depth (Part 2)
Java Concurrency in Depth (Part 3)
Java Concurrency in Depth (Part 4)
Java Concurrency in Depth (Part 5)
Java Concurrency in Depth (Part 6)
Java Concurrency in Depth (Part 7)
java-multithreading-concurrency-interview
Java Concurrency Concepts
Java concurrency (multi-threading) - Tutorial
0 comments:
Post a Comment