Concurrency is being able to do more than one thing at the same time, without affecting the final outcome. In modern programming it is everywhere. Graphical User Interfaces (GUI) do work in the background that does not interrupt the user, applications are processing on servers and websites are handeling a lot of different users. You are probably streaming audio right now while reading this blog. That is concurrency.
Concurrent Software is software that does more than one thing at a time, it doesn't use multiple processors. In fact it's possible to run multiple tasks on a single processer. How is this done? The tasks don't execute at the same time, instead the system switches between the tasks. This happens so frequently that it seems like everything is happening at once. So the multiple tasks are each making progress during the same time frame. Concurrency allows us to reduce the execution time of a data-intensive problems.
Processes and Threads are the two basic units of concurrency.
The difference between them is that a process is a program loaded into memory with all of the resources it needs to run and a thread is the unit of execution within a process.
A Process has a self-contained execution environment and generally has a complete, private set of basic run-time resources such as memory space.
Threads exist within a process, and every process has at least one thread. The thread sharing the process' resources makes for efficient communication.
A computer system normally has many active processes and threads. Each instance of a running program is a process. There can be multiple instances of a single program.
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.
Each process runs independently from other processes because they have an independent memory address space.
Java provides built in support for multithreading. Multithreading is when two or more threads are executed at the same time.
It can become complex when multiple threads need to access the same resources. Multiple threads modifying a single shared resource can lead to unpredictable behaviour.
Multiple threads are still necessary for things like running the User Interface(UI) while simultaneously monitoring message queues.
A Java Thread is a lightweight process.
To Create a thread in java follow these steps:
//Create a Worker class that extends Thread
public class Worker extends Thread {
@Override //
public void run() { // Overridden the run() method
// Loop for ten iterations.
for(int i=0; i<10; i++) {
System.out.println("Running...");
// Sleep for a while
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// Interrupted exception will occur if the Worker object's interrupt() method
// is called. interrupt() is inherited from the Thread class.
break;
}
}
}
}
If you use sleep()
, you have to catch the InterruptedException. This is thrown if a thread is interrupted while its sleeping. To interrupt a thread, call its interrupt()
method.
By calling break if the thread is interrupted, the execution of any surrounding loop will stop.
When two Worker classes are created and their inherited start()
methods are called, they both run at the same time, they run concurrently.
There are various states of a thread: New
, Runnable
, Waiting
, Blocked
, Timed Waiting
and Terminated
.
New
:
As soon as a new thread is created, it's in the New
state. The thread is not alive yet.
Runnable
:
The thread is put into a running state as soon as start()
is called.
Waiting
:
A running thread can be suspended to temporarily stop its activity.
It will pick up where it left off and return to the Runnable
state when it is allowed to resume.
Blocked
:
A thread can get Blocked
when it tries to access code that is currently locked by another thread.
The person scheduling the code is responsible for determining when threads run.
Timed Waiting
:
A Runnable
thread can change to Timed Waiting
if it is provided with an optional waiting time.
When it's waiting for another thread to perform a task, it will go into timed waiting and wait for the other thread to notify it when it's done or resume its task once the time has lapsed.
Terminated
:
A thread can be terminated in two ways. It exits normally after the program has completed its code execution, or when there are unhandled errors.
When terminated, execution is halted immediately and once a thread is terminated, it cannot be resumed.
Daemon thread in Java is a service provider thread that provides services to the user thread for background supporting tasks. The Daemon thread is dependent on the user threads. When all the user threads complete their execution, Java Virtual Machine (JVM) terminates itself. The JVM does not care whether Daemon threads are running or not and only waits for user threads to finish.
Here is a list of when you may want to use a daemon thread:
To create a Daemon thread in Java follow these steps:
package com.myjava.threads;
public class DaemonThread extends Thread{
//To specify that a thread is a daemon thread,
//call the setDaemon method with the argument true.
public DaemonThread(){
setDaemon(true);
}
public void run(){
//To determine if a thread is a daemon thread,
//use the accessor method isDaemon
System.out.println("Is this thread Daemon? - "+isDaemon());
}
public static void main(String a[]){
DaemonThread dt = new DaemonThread();
// You can also set the Daemon Constraing here : dt.setDeamon(true)
dt.start();
}
}
The JMM stipulates how the Java virtual machine (JVM) works with the computer's memory (RAM).
The JVM is a model of a whole computer, this model includes a memory model, as in: the Java Memory Model.
The JMM describes how threads in Java interact through memory. Including the description of single threaded execution of code,
the JMM provides the semantics of the Java Programming Language.
Deadlock is when there are two or more threads that are blocked forever because they are waiting for each other to exit the task.
Livelock is when two or more threads change their state continuously, and they clash with each other's state, they fail to progress because both of them are
changing state, they are too busy responding to each other to resume work.
Starvation is when a thread cannot gain access to shared resources and is unable to make progress beacuse of this.
This happens when shared resources are unavailable for long periods of time due to another thread monopolizing the resource.
run()
MethodWhat happens if you don’t override the thread class run()
method?
It is highly recommended to override run()
method because it improves the performance of the system.
When we call the start()
method on thread, it internally calls the run()
method with a newly created thread.
So, if we don’t override the run()
method, the newly created thread won’t be called and there will be no output.
Atomic operations are performed in a single unit of task without interference from other operations, they run completely independently of any other processes.
Atomic operations are a necessity in multi-threaded environments to avoid data inconsistency, and are used in many modern operating systems.
The java.util.concurrent.atomic package defines classes that support atomic operations on single variables.
All classes have get and set methods that work like reads and writes on volatile variables. A set has a happens-before relationship with any subsequent get on the same variable.
The atomic compareAndSet method also has these memory consistency features, as do the simple atomic arithmetic methods that apply to integer atomic variables.
Executor is the core interface which is an abstraction for parallel execution. It separates task from execution.
ExecutorService is an extension of Executor interface and provides a facility for returning a Future object and terminate, or shut down the thread pool.
Once the shutdown is called, the thread pool will not accept new tasks, but will complete any pending task.
The differences between Executor and ExecutorService is that Executor is a parent interface while ExecutorService is a sub-interface of Executor and extends it.
Executor uses the execute()
method for submitting tasks, while the ExecutorService uses the submit()
method.
The execute()
method accepts an object of the Runnable interface, while submit()
method can accept objects of both Runnable and Callable interfaces.
The execute()
method doesn't return any result, its return type is void but the submit()
method returns the result of a computation via a Future object.
This is also the key difference between submit()
and execute()
method, which is one of the frequently asked Java concurrency interview questions.
With Executor, you cannot cancel the task once completed, whereas with ExecutorService, you can cancel the task by using Future.cancel()
.
Executor doesn't provide any method for shutdown, but ExecutorService provides methods for shutdown of the pool
The Concurrent Collection APIs, apart from the Java Collection API, are a set of collections APIs that are designed and optimized specifically for synchronized multithreaded access.
They are grouped under the java.util.concurrent package.
The concurrent collection classes are highly scalable and low risk. The concurrent collection APIs of Java provide a range of classes that are specifically designed to deal with concurrent
operations. These classes are alternatives to the Java Collection Framework and provide similar functionality except with the additional support of concurrency.
The classes in the new concurrent collection framework include:
This post was an assignment research project.
For more information on Concurrency in Java, visit the JavaDocs
An Interface is a datatype and it is similar to a class. However, unlike classes, it can only contain constants, method signatures, default methods, static methods, and nested types.
Interfaces cannot be instantiated—they can only be implemented by classes or extended by other interfaces. When a class implements an interface, it implements all the methods defined in
the interface with the exact signature and return type. A class can also implement more than one interface.
Implementing an interface allows a class to become more formal about the behavior it promises to provide.
It's a description of duties that a class is obliged to do.
Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler.
If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.
An abstract class can have instance methods that implements a default behavior.
A Java class can implement multiple interfaces but it can extend only one abstract class.
Interfaces are slow in comparison with java abstract classes, as interfaces requires extra indirection.
Variables declared in a Java interface is by default final. An abstract class may contain non-final variables
One of the main differences is that the methods of an interface are completely abstract and cannot have implementations.
Members of a Java interface are public by default. A Java abstract class can have class members like private, protected, etc..
Interface is absolutely abstract and cannot be instantiated; A Java abstract class also cannot be instantiated, but can be invoked if a main()
exists.
Abstraction is one of the key concepts of object-oriented programming (OOP) languages. It's the process of taking away or removing characteristics from something in order to reduce it to a set of essential characteristics
The programmer hides all but the relevant data about an object in order to reduce complexity and increase efficiency
Abstraction is one of the key elements of good software design. It helps encapsulate behavior, decouple software elements and it helps having more self-contained modules amongst other things. It also helps programmers build more
complex code. Abstraction makes the application easily extendable and it makes refactoring much easier.
You can define an interface when you need to guide the programmer or make a contract specifying how the methods and fields of a type should be.
You would need to implement this interface in order to create an abstract object, you also need to provide a body for all the abstract methods of the interface and obtain the object of the implementing class.
The user who is using the interface methods, only knows the classes that implement this interface and their methods, information about the implementation is completely hidden from the user, thus achieving abstraction.
To declare a class that implements an interface, you include an implements clause in the class declaration. Your class can implement more than one interface, so the implements keyword is followed by a comma-separated list of the interfaces implemented by the class. The implements clause follows the extends clause, if there is one.
An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.
An Abstract method is a method without a body, meaning there is no implementation. If a class has an abstract method, the class itself should be declared abstract as well.
Can you instantiate an interface in Java?
Not being able to instantiate something means that you cannot create the object of an interface.
The answer is no.
It would defy the Object Oriented Model. There would be no purpose to instantiate is as 'nothing' will happen.
Some of their methods might not have any definitions
Can you declare a constructor inside an interface?
No, interface cannot have constructors.
There would be no point in having a constructor in an interface as interface cannot be instantiated. All the methods you define in an interface should be implemented by another class
(overridden).
But, you cannot override constructors in Java.
When you try and override an interface method with weaker access (private or default) then you will raise an compilation error. The methods of an interface must be public. If it is not specified, the default will be public. Therefore when the subclass which implements the interface overrides, it can only use the same specifier or a stronger one. No stronger specifier than public exists in Java. For this, reason, all the methods of interface must be overridden with public only.
This post was an assignment research project.
For more information on Interfaces in Java, visit the JavaDocs
Copyright © 2020, Estine van der Berg, All Rights Reserved