UNIT 5
Multithreading in Java
The Java Thread Model
The Java run-time system depends on threads for many things, and all the class libraries are designed with multithreading in mind. In fact, Java uses threads to enable the entire environment to be asynchronous. This helps reduce inefficiency by preventing the waste of CPU cycles.
The value of a multithreaded environment is best understood in contrast to its counterpart. Single-threaded systems use an approach called an event loop with polling. In this model, a single thread of control runs in an infinite loop, polling a single event queue to decide what to do next. Once this polling mechanism returns with, say, a signal that a network file is ready to be read, then the event loop dispatches control to the appropriate event handler. Until this event handler returns, nothing else can happen in the program. This wastes CPU time. It can also result in one part of a program dominating the system and preventing any other events from being processed. In general, in a single-threaded environment, when a thread blocks (that is, suspends execution) because it is waiting for some resource, the entire program stops running.
The benefit of Java’s multithreading is that the main loop/polling mechanism is eliminated. One thread can pause without stopping other parts of your program. For example, the idle time created when a thread reads data from a network or waits for user input can be utilized elsewhere. Multithreading allows animation loops to sleep for a second between each frame without causing the whole system to pause. When a thread blocks in a Java program, only the single thread that is blocked pauses. All other threads continue to run.
As most readers know, over the past few years, multi-core systems have become commonplace. Of course, single-core systems are still in widespread use. It is important to understand that Java’s multithreading features work in both types of systems. In a single-core system, concurrently executing threads share the CPU, with each thread receiving a slice of CPU time. Therefore, in a single-core system, two or more threads do not actually run at the same time, but idle CPU time is utilized. However, in multi-core systems, it is possible for two or more threads to actually execute simultaneously. In many cases, this can further improve program efficiency and increase the speed of certain operations.
Threads exist in several states. Here is a general description. A thread can be running. It can be ready to run as soon as it gets CPU time. A running thread can be suspended, which temporarily halts its activity. A suspended thread can then be resumed, allowing it to pick up where it left off. A thread can be blocked when waiting for a resource. At any time, a thread can be terminated, which halts its execution immediately. Once terminated, a thread cannot be resumed.
Thread Priorities
Java assigns to each thread a priority that determines how that thread should be treated with respect to the others. Thread priorities are integers that specify the relative priority of one thread to another. As an absolute value, a priority is meaningless; a higher-priority thread doesn’t run any faster than a lower-priority thread if it is the only thread running.
Instead, a thread’s priority is used to decide when to switch from one running thread to the next. This is called a context switch. The rules that determine when a context switch takes place are simple:
A thread can voluntarily relinquish control. This is done by explicitly yielding, sleeping, or blocking on pending I/O. In this scenario, all other threads are examined, and the highest-priority thread that is ready to run is given the CPU.
A thread can be preempted by a higher-priority thread. In this case, a lower-priority thread that does not yield the processor is simply preempted—no matter what it is doing— by a higher-priority thread. Basically, as soon as a higher-priority thread wants to run, it does. This is called preemptive multitasking.
In cases where two threads with the same priority are competing for CPU cycles, the situation is a bit complicated. For operating systems such as Windows, threads of equal priority are time-sliced automatically in round-robin fashion. For other types of operating systems, threads of equal priority must voluntarily yield control to their peers. If they don’t, the other threads will not run.
Synchronization
Because multithreading introduces an asynchronous behavior to your programs, there must be a way for you to enforce synchronicity when you need it. For example, if you want two threads to communicate and share a complicated data structure, such as a linked list, you need some way to ensure that they don’t conflict with each other. That is, you must prevent one thread from writing data while another thread is in the middle of reading it. For
this purpose, Java implements an elegant twist on an age-old model of interprocess synchronization: the monitor. The monitor is a control mechanism first defined by C.A.R. Hoare. You can think of a monitor as a very small box that can hold only one thread. Once a thread enters a monitor, all other threads must wait until that thread exits the monitor. In this way, a monitor can be used to protect a shared asset from being manipulated by more than one thread at a time.
In Java, there is no class “Monitor”; instead, each object has its own implicit monitor that is automatically entered when one of the object’s synchronized methods is called. Once a thread is inside a synchronized method, no other thread can call any other synchronized method on the same object. This enables you to write very clear and concise multithreaded code, because synchronization support is built into the language.
Messaging
After you divide your program into separate threads, you need to define how they will communicate with each other. When programming with some other languages, you must depend on the operating system to establish communication between threads. This, of course, adds overhead. By contrast, Java provides a clean, low-cost way for two or more threads to talk to each other, via calls to predefined methods that all objects have. Java’s messaging system allows a thread to enter a synchronized method on an object, and then wait there until some other thread explicitly notifies it to come out.
The Thread Class and the Runnable Interface
Java’s multithreading system is built upon the Thread class, its methods, and its companion interface, Runnable. Thread encapsulates a thread of execution. Since you can’t directly refer to the ethereal state of a running thread, you will deal with it through its proxy, the Thread instance that spawned it. To create a new thread, your program will either extend Thread or implement the Runnable interface.
The Thread class defines several methods that help manage threads. Several of those used in this chapter are shown here:
Fig 1 - Thread class defines several methods
Thus far, all the examples in this book have used a single thread of execution. The remainder of this chapter explains how to use Thread and Runnable to create and manage threads, beginning with the one thread that all Java programs have: the main thread.
Java is a multi-threaded programming language which means we can develop multi-threaded program using Java. A multi-threaded program contains two or more parts that can run concurrently and each part can handle a different task at the same time making optimal use of the available resources specially when your computer has multiple CPUs.
By definition, multitasking is when multiple processes share common processing resources such as a CPU. Multi-threading extends the idea of multitasking into applications where you can subdivide specific operations within a single application into individual threads. Each of the threads can run in parallel. The OS divides processing time not only among different applications, but also among each thread within an application.
Multi-threading enables you to write in a way where multiple activities can proceed concurrently in the same program.
Life Cycle of a Thread
A thread goes through various stages in its life cycle. For example, a thread is born, started, runs, and then dies. The following diagram shows the complete life cycle of a thread.
Fig 2 - The complete life cycle of a thread
Following are the stages of the life cycle −
Thread Priorities
Every Java thread has a priority that helps the operating system determine the order in which threads are scheduled.
Java thread priorities are in the range between MIN_PRIORITY (a constant of 1) and MAX_PRIORITY (a constant of 10). By default, every thread is given priority NORM_PRIORITY (a constant of 5).
Threads with higher priority are more important to a program and should be allocated processor time before lower-priority threads. However, thread priorities cannot guarantee the order in which threads execute and are very much platform dependent.
Create a Thread by Implementing a Runnable Interface
If your class is intended to be executed as a thread then you can achieve this by implementing a Runnable interface. You will need to follow three basic steps −
Step 1
As a first step, you need to implement a run() method provided by a Runnable interface. This method provides an entry point for the thread and you will put your complete business logic inside this method. Following is a simple syntax of the run() method −
public void run( )
Step 2
As a second step, you will instantiate a Thread object using the following constructor −
Thread(Runnable threadObj, String threadName);
Where, threadObj is an instance of a class that implements the Runnable interface and threadName is the name given to the new thread.
Step 3
Once a Thread object is created, you can start it by calling start() method, which executes a call to run( ) method. Following is a simple syntax of start() method −
void start();
Example
Here is an example that creates a new thread and starts running it −
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2.start();
}
}
This will produce the following result −
Output
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
Create a Thread by Extending a Thread Class
The second way to create a thread is to create a new class that extends Thread class using the following two simple steps. This approach provides more flexibility in handling multiple threads created using available methods in Thread class.
Step 1
You will need to override run( ) method available in Thread class. This method provides an entry point for the thread and you will put your complete business logic inside this method. Following is a simple syntax of run() method −
public void run( )
Step 2
Once Thread object is created, you can start it by calling start() method, which executes a call to run( ) method. Following is a simple syntax of start() method −
void start( );
Example
Here is the preceding program rewritten to extend the Thread −
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
ThreadDemo T2 = new ThreadDemo( "Thread-2");
T2.start();
}
}
This will produce the following result −
Output
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
Thread Methods
Following is the list of important methods available in the Thread class.
Sr.No. | Method & Description |
1 | public void start() Starts the thread in a separate path of execution, then invokes the run() method on this Thread object. |
2 | public void run() If this Thread object was instantiated using a separate Runnable target, the run() method is invoked on that Runnable object. |
3 | public final void setName(String name) Changes the name of the Thread object. There is also a getName() method for retrieving the name. |
4 | public final void setPriority(int priority) Sets the priority of this Thread object. The possible values are between 1 and 10. |
5 | public final void setDaemon(boolean on) A parameter of true denotes this Thread as a daemon thread. |
6 | public final void join(long millisec) The current thread invokes this method on a second thread, causing the current thread to block until the second thread terminates or the specified number of milliseconds passes. |
7 | public void interrupt() Interrupts this thread, causing it to continue execution if it was blocked for any reason. |
8 | public final boolean isAlive() Returns true if the thread is alive, which is any time after the thread has been started but before it runs to completion. |
The previous methods are invoked on a particular Thread object. The following methods in the Thread class are static. Invoking one of the static methods performs the operation on the currently running thread.
Sr.No. | Method & Description |
1 | public static void yield() Causes the currently running thread to yield to any other threads of the same priority that are waiting to be scheduled. |
2 | public static void sleep(long millisec) Causes the currently running thread to block for at least the specified number of milliseconds. |
3 | public static boolean holdsLock(Object x) Returns true if the current thread holds the lock on the given Object. |
4 | public static Thread currentThread() Returns a reference to the currently running thread, which is the thread that invokes this method. |
5 | public static void dumpStack() Prints the stack trace for the currently running thread, which is useful when debugging a multithreaded application. |
Example
The following ThreadClassDemo program demonstrates some of these methods of the Thread class. Consider a class DisplayMessage which implements Runnable −
// File Name : DisplayMessage.java
// Create a thread to implement Runnable
public class DisplayMessage implements Runnable {
private String message;
public DisplayMessage(String message) {
this.message = message;
}
public void run() {
while(true) {
System.out.println(message);
}
}
}
Following is another class which extends the Thread class −
// File Name : GuessANumber.java
// Create a thread to extentd Thread
public class GuessANumber extends Thread {
private int number;
public GuessANumber(int number) {
this.number = number;
}
public void run() {
int counter = 0;
int guess = 0;
do {
guess = (int) (Math.random() * 100 + 1);
System.out.println(this.getName() + " guesses " + guess);
counter++;
} while(guess != number);
System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**");
}
}
Following is the main program, which makes use of the above-defined classes −
// File Name : ThreadClassDemo.java
public class ThreadClassDemo {
public static void main(String [] args) {
Runnable hello = new DisplayMessage("Hello");
Thread thread1 = new Thread(hello);
thread1.setDaemon(true);
thread1.setName("hello");
System.out.println("Starting hello thread...");
thread1.start();
Runnable bye = new DisplayMessage("Goodbye");
Thread thread2 = new Thread(bye);
thread2.setPriority(Thread.MIN_PRIORITY);
thread2.setDaemon(true);
System.out.println("Starting goodbye thread...");
thread2.start();
System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
thread3.start();
try {
thread3.join();
} catch (InterruptedException e) {
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
thread4.start();
System.out.println("main() is ending...");
}
}
This will produce the following result. You can try this example again and again and you will get a different result every time.
Output
Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......
Synchronization in java is the capability to control the access of multiple threads to any shared resource.
Java Synchronization is better option where we want to allow only one thread to access the shared resource.
Why use Synchronization
The synchronization is mainly used to
Types of Synchronization
There are two types of synchronization
Here, we will discuss only thread synchronization.
Thread Synchronization
There are two types of thread synchronization mutual exclusive and inter-thread communication.
- Synchronized method.
- Synchronized block.
- static synchronization.
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while sharing data. This can be done by three ways in java:
Concept of Lock in Java
Synchronization is built around an internal entity known as the lock or monitor. Every object has an lock associated with it. By convention, a thread that needs consistent access to an object's fields has to acquire the object's lock before accessing them, and then release the lock when it's done with them.
From Java 5 the package java.util.concurrent.locks contains several lock implementations.
Understanding the problem without Synchronization
In this example, there is no synchronization, so output is inconsistent. Let's see the example:
Output: 5
100
10
200
15
300
20
400
25
500
Java synchronized method
If you declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.
Output: 5
10
15
20
25
100
200
300
400
500
Example of synchronized method by using annonymous class
In this program, we have created the two threads by annonymous class, so less coding is required.
Output: 5
10
15
20
25
100
200
300
400
500
JMS (Java Message Service) is an API that provides the facility to create, send and read messages. It provides loosely coupled, reliable and asynchronous communication.
JMS is also known as a messaging service.
Understanding Messaging
Messaging is a technique to communicate applications or software components.
JMS is mainly used to send and receive message from one application to another.
Requirement of JMS
Generally, user sends message to application. But, if we want to send message from one application to another, we need to use JMS API.
Consider a scenario, one application A is running in INDIA and another application B is running in USA. To send message from A application to B, we need to use JMS.
Advantage of JMS
1) Asynchronous: To receive the message, client is not required to send request. Message will arrive automatically to the client.
2) Reliable: It provides assurance that message is delivered.
Messaging Domains
There are two types of messaging domains in JMS.
1) Point-to-Point (PTP) Messaging Domain
In PTP model, one message is delivered to one receiver only. Here, Queue is used as a message oriented middleware (MOM).
The Queue is responsible to hold the message until receiver is ready.
In PTP model, there is no timing dependency between sender and receiver.
Fig 3 - No timing dependency
2) Publisher/Subscriber (Pub/Sub) Messaging Domain
In Pub/Sub model, one message is delivered to all the subscribers. It is like broadcasting. Here, Topic is used as a message oriented middleware that is responsible to hold and deliver messages.
In PTP model, there is timing dependency between publisher and subscriber.
Fig 4 - Timing dependency
Fig 5 - JMS Programming Model
JMS Queue Example
To develop JMS queue example, you need to install any application server. Here, we are using glassfish3 server where we are creating two JNDI.
After creating JNDI, create server and receiver application. You need to run server and receiver in different console. Here, we are using eclipse IDE, it is opened in different console by default.
1) Create connection factory and destination resourceOpen server admin console by the URL http://localhost:4848
Login with the username and password.
Click on the JMS Resource -> Connection Factories -> New, now write the pool name and select the Resource Type as QueueConnectionFactory then click on ok button.
Click on the JMS Resource -> Destination Resources -> New, now write the JNDI name and physical destination name then click on ok button.
2) Create sender and receiver applicationLet's see the Sender and Receiver code. Note that Receiver is attached with listener which will be invoked when user sends message.
File: MySender.java
File: MyReceiver.java
File: MyListener.java
Run the Receiver class first then Sender class.
JMS Example
It is same as JMS Queue, but you need to change Queue to Topic, Sender to Publisher and Receiver to Subscriber.
You need to create 2 JNDI named myTopicConnectionFactory and myTopic.
File: MySender.java
File: MyReceiver.java
File: MyListener.java
Key takeaway
The Java Thread Model
The Java run-time system depends on threads for many things, and all the class libraries are designed with multithreading in mind. In fact, Java uses threads to enable the entire environment to be asynchronous. This helps reduce inefficiency by preventing the waste of CPU cycles.
The value of a multithreaded environment is best understood in contrast to its counterpart. Single-threaded systems use an approach called an event loop with polling. In this model, a single thread of control runs in an infinite loop, polling a single event queue to decide what to do next. Once this polling mechanism returns with, say, a signal that a network file is ready to be read, then the event loop dispatches control to the appropriate event handler. Until this event handler returns, nothing else can happen in the program. This wastes CPU time. It can also result in one part of a program dominating the system and preventing any other events from being processed. In general, in a single-threaded environment, when a thread blocks (that is, suspends execution) because it is waiting for some resource, the entire program stops running.
A thread can be created by implementing the Runnable interface and overriding the run() method.
The Main thread in Java is the one that begins executing when the program starts. All the child threads are spawned from the Main thread. Also, it is the last thread to finish execution as various shut-down actions are performed by it.
A program that demonstrates this is given as follows:
Example
public class Demo {
public static void main(String args[]) {
Thread t = Thread.currentThread();
System.out.println("Main thread: " + t);
t.setName("current");
System.out.println("Current thread: " + t);
try {
for (int i = 1; i <= 5; i++) {
System.out.println(i);
Thread.sleep(10);
}
} catch (InterruptedException e) {
System.out.println("Main thread is interrupted");
}
System.out.println("Exiting the Main thread");
}
}
Output
Main thread: Thread[main,5,main]
Current thread: Thread[current,5,main]
1
2
3
4
5
Exiting the Main thread
Key takeaway
A thread can be created by implementing the Runnable interface and overriding the run() method.
The Main thread in Java is the one that begins executing when the program starts. All the child threads are spawned from the Main thread. Also, it is the last thread to finish execution as various shut-down actions are performed by it.
The isAlive() method of thread class tests if the thread is alive. A thread is considered alive when the start() method of thread class has been called and the thread is not yet dead. This method returns true if the thread is still running and not finished.
Syntax
Return
This method will return true if the thread is alive otherwise returns false.
Example
Output:
before starting thread isAlive: false
after starting thread isAlive: true
is run() method isAlive true
The join() method waits for a thread to die. In other words, it causes the currently running threads to stop executing until the thread it joins with completes its task.
Syntax:
public void join()throws InterruptedException |
public void join(long milliseconds)throws InterruptedException |
Example of join() method
Output:1
2
3
4
5
1
1
2
2
3
3
4
4
5
5
As you can see in the above example,when t1 completes its task then t2 and t3 starts executing. |
Example of join(long miliseconds) method
Output:1
2
3
1
4
1
2
5
2
3
3
4
4
5
5
In the above example,when t1 is completes its task for 1500 miliseconds(3 times) then t2 and t3 starts executing. |
getName(),setName(String) and getId() method:
public String getName() |
public void setName(String name) |
public long getId() |
Output:Name of t1:Thread-0
Name of t2:Thread-1
id of t1:8
running...
After changling name of t1:Sonoo Jaiswal
running...
The currentThread() method:
The currentThread() method returns a reference to the currently executing thread object. |
Syntax:
public static Thread currentThread() |
Example of currentThread() method
Output:Thread-0
Thread-1
Key takeaway
The isAlive() method of thread class tests if the thread is alive. A thread is considered alive when the start() method of thread class has been called and the thread is not yet dead. This method returns true if the thread is still running and not finished.
Syntax
Return
This method will return true if the thread is alive otherwise returns false.
What are the uses of JavaScript?
JavaScript is a light-weight object-oriented programming language that is used by several websites for scripting the webpages. It is an interpreted, full-fledged programming language. JavaScript enables dynamic interactivity on websites when it is applied to an HTML document.
JavaScript helps the users to build modern web applications to interact directly without reloading the page every time. JavaScript is commonly used to dynamically modify HTML and CSS to update a user interface by the DOM API. It is mainly used in web applications.
Let's discuss the uses of JavaScript. Some of the uses of JavaScript are representing in the following image.
Fig 6 - uses of JavaScript
1. Web Applications
As day-by-day there is a continuous improvement in the browsers, so JavaScript gained popularity for making robust web applications. We can understand it by taking the example of Google Maps. In Maps user just requires to click and drag the mouse; the details are visible just by a click. There is a use of JavaScript behind these concepts.
2. Web Development
JavaScript is commonly used for creating web pages. It allows us to add dynamic behavior to the webpage and add special effects to the webpage. On websites, it is mainly used for validation purposes. JavaScript helps us to execute complex actions and also enables the interaction of websites with visitors. Using JavaScript, it is also possible to load the content in a document without reloading the webpage.
3. Mobile Applications
Now a day's mobile devices are broadly used for accessing the internet. Using JavaScript, we can also build an application for non-web contexts. The features and uses of JavaScript make it a powerful tool for creating mobile applications. The React Native is the widely used JavaScript framework for creating mobile applications. Using React Native, we can build mobile applications for different operating systems. We do not require writing different codes for the iOS and Android operating systems. We only need to write it once and run it on different platforms.
4. Game
JavaScript is also used for creating games. It has various libraries and frameworks for creating a game. The game can either be a 2D or 3D. Some JavaScript game engines such as PhysicsJS, Pixi.js help us to create a web game. We can also use the WebGL (web graphics library), which is the JavaScript API to render 2D and 3D images on browsers.
5. Presentations
JavaScript also helps us to create presentations as a website. The libraries, such as RevealJs, and BespokeJs, can be used to create a web-based slide deck. They are easier to use, so we can easily make something amazing in a short time.
The Reveal.js is used to create interactive and beautiful slide decks with the help of HTML. These presentations work great with mobile devices and tablets. It also supports all of the CSS color formats. The BespokeJS includes animated bullet lists, responsive scaling, and a wide variety of features.
6. Server Applications
A large number of web applications have a server-side to them. JavaScript is used to generate content and handle HTTP requests. JavaScript can also run on servers through Node.js. The Node.js provides an environment containing the necessary tools required for JavaScript to run on servers.
7. Web Servers
A web server can be created by using Node.js. Node.js is event-driven and not waits for the response of the previous call. The servers created using Node.js are fast and don't use buffering and transfer chunks of data. The HTTP module can be used to create the server by using the createServer() method. This method executes when someone tries to access the port 8080. As a response, the HTTP server should display HTML and should be included in the HTTP header.
In this article, we discussed various JavaScript applications. JavaScript has various other uses that help us to improve the performance of webpages. The other uses of JavaScript are listed as follows:
Key takeaway
JavaScript is a light-weight object-oriented programming language that is used by several websites for scripting the webpages. It is an interpreted, full-fledged programming language. JavaScript enables dynamic interactivity on websites when it is applied to an HTML document.
JavaScript helps the users to build modern web applications to interact directly without reloading the page every time. JavaScript is commonly used to dynamically modify HTML and CSS to update a user interface by the DOM API. It is mainly used in web applications.
Some would think of it as a language used at frontend, can be used to trigger any event and handle that event, can be used to send a request and get a response from the backend or from an API.
Nowadays developers are also using it as a platform to implement backend, to connect with the server and perform operations on the server.
Javascript is basically a high-level, interpreted, event-driven, object-oriented and functional scripting language.
If we go in the history of javascript, it was just used to apply the logic and handle the events at the frontend. But, now there are a large number of frameworks that are built for javascript to implement the various functionalities. There are a number of libraries that are used across the world for UI and functionalities.
Vanilla Javascript is the basic Javascript i.e not extended by any frameworks. Frameworks are used in the javascript to overcome some shortcomings and to implement new functionalities.
Javascript Frameworks
Let’s go deeper into Javascript Frameworks.
Think about it as when one starts building a house by making its own building material, it means building a house from scratch rather than taking already made material.
Similarly, in the case of javascript, frameworks are the collections of pre-defined libraries which can be directly used in the code and rather than writing the whole code from scratch.
For Example -:
If there is a need to embed a javascript carousel on your webpage, we can use UI frameworks of the javascript for this purpose and their other functionalities as well. Material.js, Ant-Design are examples of such frameworks.
There are a vast number of javascript frameworks available today, but very few are used on a large scale.
So, the biggest question is, which of the frameworks are most popular today and Why?
According to the statistics of Stackover Flow, before 2016 jquery was the most widely used library. 8% of the questions asked were from the jquery itself. In 2016, this trend completely changed when Angular and React were introduced in the javascript world. They were quickly adopted by everyone as they provide a well-defined entire structure for a Single Page Application (SPA).
There are other frameworks that are popular and widely used, but not as popular as react and angular.
The Top 5 Javascript Frameworks
Now, we will discuss more ReactJS and AngularJS
ReactJS:
ReactJS is the open-source javascript framework created at facebook. It is used for building User Interface for Single Page Applications. It handles the view layer of the Model View Controller (MVC) architecture.
JSX:
It uses JSX, not regular javascript. JSX is HTML coded tags that are used to call subcomponents. These HTML tags are converted into javascript calls and we can also use plain javascript in the curly braces inside the JSX.
Single-Way Data Flow
In React, the immutable properties are transferred to its components.
Fig 7 - Single-Way Data Flow
At redux the data is immutable at the top, it flows down the path in the form of properties.
Later, when the data has to be changed the callback functions use calls in the upward flow and change the immutable data utilizing certain properties and methods.
These properties can not be changed directly. They can only be changed with the help of callback functions that are called in the upward flow. Basically, properties or data only flow down the hierarchy of components and if any action is called, it goes back in the hierarchy.
It uses a concept of states and properties so, every time the state changes, react does not change the whole Document Object Model (DOM), it only renders the component that actually changed.
Fig 8 - example
This is how React.js updates the Document Object Model ( It only changes the part of the component that is updated )
AngularJS:
AngularJS is the open source based on the Model View Controller (MVC) architecture. It is used to create dynamic HTML webpages. Its MVC architecture lets us implement the business layer, data layer, and presentation layer separately. AngularJS was started as a project in Google, later on, it became like an open-source project. Due to ideas from the communities, its framework is always kept up to date.
AngularJS ArchitectureFig 9 - AngularJS ArchitectureData can be bind with HTML tags easily. We don’t need to learn special syntax to bind the data with HTML. We have to use simple javascript and HTML along with small angular code snippets to make it work.
Writing Less CodeWe have to write very less in case of manipulating DOM. In javascript, we make a large number of changes when manipulating the DOM, but it’s not with Angular.
Key takeaway
Some would think of it as a language used at frontend, can be used to trigger any event and handle that event, can be used to send a request and get a response from the backend or from an API.
Nowadays developers are also using it as a platform to implement backend, to connect with the server and perform operations on the server.
Javascript is basically a high-level, interpreted, event-driven, object-oriented and functional scripting language.
If we go in the history of javascript, it was just used to apply the logic and handle the events at the frontend. But, now there are a large number of frameworks that are built for javascript to implement the various functionalities. There are a number of libraries that are used across the world for UI and functionalities.
References:
1. T. W. Pratt, M. V. Zelkowitz, "Programming Languages Design and Implementation‖, 4th Ed, PHI, ISBN 81-203-2035-2.
2. Sebesta R., "Concepts of Programming Languages", 4th Edition, Pearson Education, ISBN81-7808-161-X.
3. Herbert Schildt, "The Complete Reference Java", 9th Ed, TMH,ISBN: 978-0-07-180856-9.
4. Dr.R. Nageshwar Rao, "Core Java: An Integrated Approach", Dreamtech Press
5. Deugo, ―Java Gems‖, Cambridge University Press, ISBN 10: 0521648246 ISBN 13: 9780521648240
6. Carl Townsend,” Programming in turbo PROLOG”, Tata-McGraw Hill
7. Ivan Bratko, “Prolog Programming for Artificial Intelligence”, Wesley Publishers Limited
8. Winston P., Klaus B., Horn P., "LISP", 3rd Edition, Pearson Education, 81 - 7808 -155-5
9. Carlo Ghezzi, Mehdi Jazayeri, ―Programming Language Concepts‖,3rd Ed, Wiley Publication ISBN : 978-81-265-1861-6.