Concurrent Programming in Java – PART ONE

Home /

Table of Contents

Computer users take it for granted that their systems can perform multiple tasks at once. They believe they can keep working in a word processor while other programs download files, manage the print queue, and stream audio. Even a single application is frequently expected to do multiple things at once. For example, that streaming audio application must read digital audio from the network, decompress it, manage playback, and update its display all at the same time. Even if the word processor is busy reformatting text or updating the display, it should always be ready to respond to keyboard and mouse events. Concurrent software is software that can do such things.

The Java platform is built from the ground up to support concurrent programming, with basic concurrency support built into the Java programming language and class libraries. The Java platform has also included high-level concurrency APIs since version 5.0. This tutorial introduces the platform’s basic concurrency support and summarizes some of the java.util.concurrent packages’ high-level APIs.

Let us build a simple messaging application! A messaging app is a chat application or platform that allows users to communicate with one another via computers or mobile devices. Examples of messaging applications are Facebook Messenger, WhatsApp, WeChat, or Slack (just to name a few). We will create a messaging application named MessageApp. You can send a message, and all your friends in the MessageApp will receive it. It is like a group chat app, made solely for your friends. Instead of just reading the other participants’ messages, you can also send messages to others.

We will develop MessageApp using our knowledge of networking in Java and working with GUI in Java.

How To Write A Chat Client?

The Chat client application will be written in two stages. We’ll start with a send-only version that sends messages to the server but does not receive any messages from other participants. This adds an exciting and mysterious twist to the entire chat room concept. Then we’ll go all out and make one that both sends and receives chat messages.

Version One: send-only

Code Outline

import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.JTextField;

public class SimpleChatClientATest {
    JTextField outgoing;
    PrintWriter writer;
    Socket socket;

public void go() {

    // make gui and register a listener with the send button
    // call the setUpNetworking() method

}

private void setUpNetworking() {

    // make a Socket, then make a PrintWriter
    // assign the PrintWriter to writer instance variable

}

public class SendButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent ev) {
        // get the text from the text field and
        // send it to the server using the writer (a PrintWriter)
    }
} // close SendButtonListener inner class
} // close outer class

THE CODE

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SimpleChatClientA {

    private String ipAddress;
    private int port;
    private JTextField outgoing;
    private PrintWriter writer;
    private Socket socket;

    public SimpleChatClientA(String ipAddress, int port){

        this.ipAddress = ipAddress;
        this.port = port;
    }

    public void go() {

        JFrame frame = new JFrame("Simple Chat Client");
        JPanel mainPanel = new JPanel();
        outgoing = new JTextField(20);
        JButton sendButton = new JButton("Send");
        sendButton.addActionListener(new SendButtonListener());
        mainPanel.add(outgoing);
        mainPanel.add(sendButton);
        frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
        setUpNetworking();
        frame.setSize(400,500);
        frame.setVisible(true);

    } // close go
    private void setUpNetworking() {
        try {
            socket = new Socket(ipAddress, port);
            writer = new PrintWriter(socket.getOutputStream());
            System.out.println("networking established");
        } catch(IOException ex) {
            ex.printStackTrace();
        }
    } // close setUpNetworking
    public class SendButtonListener implements ActionListener {

        public void actionPerformed(ActionEvent ev) {
            try {
                writer.println(outgoing.getText());
                writer.flush();
            } catch(Exception ex) {
                ex.printStackTrace();
            }
                outgoing.setText("");
                outgoing.requestFocus();
            }
           
    } // close SendButtonListener inner class
    public static void main(String[] args) {

        new SimpleChatClientA("localhost",5000).go();
   
    }
} // close outer class

If you compile and run this program you will see something like this:

XzZW7VqJ eJUa7 GQMlAqaZXbeapFiMk8 tdub84auJKOYiSgalsqEuWUv7CcIrCvlTnrIZ8ottJez8mTJqumPgGRmwyVQ9 2w15SW3J FvprLFEuqoC5dqQYuCUt7QdvBVvw8gKrq7aCpE0E3yog hXhE OMcebZtzlPNhEEMv34LMVBlQzZGmg - Concurrent Programming in Java - PART ONE

You will see an user interface as well as some error messages. This happens because we have not yet made the server and put it online. So the client app has nothing to connect to.

If you want to try it right away, enter the chat server code found at the end of this tutorial. Start the server in one terminal first. Next, launch this client from another terminal.

Version Two: Send And Receive

5EgAF f 7Tv6Oc1LfE7fhNA6mdwjq2rmPb MnHO8hi78Edg1tnOqfasWQvkgempYEG iSOR46HTlqvN6evB0eMXMHy6DO 7UO4gEccX28OibnBa MzP5gTfx7v2TSgCB7 PQ0nLzU1PVx aoCbkOVLwdFGeidJm3ZFfW - Concurrent Programming in Java - PART ONE

As soon as the message is received by the server, the server sends it to all client participants. When a client sends a message, it does not appear in the incoming message display area until it is sent to everyone by the server.

HOW DO YOU GET MESSAGE FROM SERVER?

It should be simple; when you set up the networking, create an input stream as well (probably a BufferedReader). Then, using readLine(), read the messages.

WHEN do you get messages from the server?

Think about that. What are the options?

Option one: Every 20 seconds, poll the server.
Pros: It can be easily done.
Cons: How does the server know what you have and have not seen? The server would have to store the messages rather than simply distribute and forget each time one arrived. And why only 20 seconds? A delay like this has an impact on usability, but as you reduce the delay, you risk overloading your server. Inefficient.

Option Two: Read something in from the server each time the user sends a message.
Pros: Do-able, very easyd
Cons: This is a stupid solution. Why would you check for messages at such an arbitrary time? What if a user only lurks and never sends anything?

Option Three: Read messages as soon as they’re sent from the server
Pros: Most efficient, easiest to use.
Cons: How do you do two things at once? What would you do with this code? A loop somewhere that was always waiting to read from the server would be required. But where would that end up? Nothing happens after you launch the GUI until an event is fired by a GUI component.
You already know we're going with option three.

We want something to run continuously, checking for server messages but not interfering with the user’s ability to interact with the GUI! So, while the user is happily typing new messages or scrolling through the incoming messages, we want something to be reading in new input from the server behind the scenes.

That means we’re in desperate need of a new thread. A new, distinct stack.

Everything we did in the Send-Only version (version one) should continue to work, while a new process reads information from the server and displays it in the incoming text area.

No, not quite. Unless your computer has multiple processors, each new Java thread is not a separate process running on the operating system. But it almost feels that way.

There are two basic execution units in concurrent programming: processes and threads. Concurrent programming is mostly concerned with threads in the Java programming language. However, processes are also essential.

A computer system typically has a large number of active processes and threads. This is true even in systems with a single execution core and thus only one thread executing at any given time. Through an OS feature known as time slicing, processing time for a single core is shared among processes and threads.

Computer systems with multiple processors or processors with multiple execution cores are becoming increasingly common. This greatly improves a system’s ability to execute processes and threads concurrently — but concurrency is possible even on simple systems lacking multiple processors or execution cores.

Processes

A process has its own execution environment. A process typically has a complete, private set of basic run-time resources, including its own memory space.

Processes are frequently confused with programs or applications. What the user perceives as a single application may, in fact, be a collection of interconnected processes. Most operating systems support Inter Process Communication (IPC) resources such as pipes and sockets to facilitate communication between processes. IPC is used to communicate not only between processes on the same system, but also between processes on different systems.

Most Java virtual machine implementations run as a single process. A ProcessBuilder object can be used by a Java application to create new processes. This lesson does not cover multi process applications.

Threads

Threads are sometimes referred to as 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, such as memory and open files. This results in efficient, but potentially problematic, communication.

The Java platform requires multithreaded execution. Every application has at least one thread — or several, if you count “system” threads that handle things like memory management and signal handling. However, from the perspective of an application programmer, you start with just one thread, known as the main thread. As we’ll see in the following section, this thread has the ability to create new threads.

Share The Tutorial With Your Friends
Twiter
Facebook
LinkedIn
Email
WhatsApp
Skype
Reddit
Other Recommended Article