Background

Relevant concepts

What is multithreading

We call the components of the Program threads. In other words, a thread is a lightweight Process in a program.

Multithreading is a Java feature that allows multiple parts of a program (i.e., threads) to execute concurrently in order to maximize CPU utilization.

Multithreading is a Java feature that allows concurrent execution of two or more parts of a program for maximum utilization of CPU. Each part of such program is called a thread. So, threads are light-weight processes within a process.

– www.geeksforgeeks.org/multithread…

Thread state

polling

Samples

Polling is a process called Polling, in which a loop executes a certain logical judgment and does not Polling until the judgment condition is true. Polling is a waste of CPU resources.

The process of testing a condition repeatedly till it becomes true is known as polling.Polling is usually implemented with the help of loops to check whether a particular condition is true or not. If it is true, certain action is taken. This waste many CPU cycles and makes the implementation inefficient.

– www.geeksforgeeks.org/inter-threa…

An example implementation of polling is provided below.

The Message:

IsAvailable the initial value is false. When set to true, the polling body is executed.

Be careful to use thread-safe AtomicBoolean; if you use Boolean, you can expect unexpected results in multithreaded situations.

import lombok.Getter;
import lombok.Setter;
import java.util.concurrent.atomic.AtomicBoolean;

@Setter
@Getter
public class Message {
    private AtomicBoolean isAvailable = new AtomicBoolean(false);
    private String msg;
    public Message(String str) {
        this.msg = str; }}Copy the code

PollingWaiter:


import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class PollingWaiter implements Runnable {
    private Message msg;
    public PollingWaiter(Message m) {
        this.msg = m;
    }

    @Override
    public void run(a) {
        String name = Thread.currentThread().getName();
        synchronized (msg) {
            int count = 0;
            System.out.println(name + " : waiter starting at time: " + LocalDateTime.now().format(DateTimeFormatter.ISO_TIME));
            while(! msg.getIsAvailable().get()) { count++; } System.out.println(name +" : msg is available at time: " + LocalDateTime.now().format(DateTimeFormatter.ISO_TIME));
            System.out.println(name + " : msg is available after count: " + count);
            System.out.println(name + " : processed: "+ msg.getMsg()); }}}Copy the code

Perform tests:

After sleeping for 3 seconds, poll the internal code.

import java.util.concurrent.atomic.AtomicBoolean;

public class WaitNotifyTest {

    public static void main(String[] args) {
        testPolling();
    }

    public static void testPolling(a) {

        Message msg = new Message("process it");

        PollingWaiter waiter = new PollingWaiter(msg);

        new Thread(waiter, "PollingWaiter").start();

        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        msg.setIsAvailable(new AtomicBoolean(true));
        System.out.println("over"); }}Copy the code

Output result:

PollingWaiter : waiter starting at time: 14:26:08.482
over
PollingWaiter : msg is available at time: 14:26:11.402
PollingWaiter : msg is available after count: -69547606
PollingWaiter : processed: process it
Copy the code

Wait and notify

In addition to polling, Java implements communication between threads through wait and Notify mechanisms. Wait causes a thread holding an object to wait and block, while notify causes a thread holding an object to regain CPU resources and run again.

Because the wait and notify methods are implemented in the java.lang.Object class, they are available to all subclasses.

The wait and notify related methods need to be executed in a synchronized block.

Methods to introduce

Here is a brief overview of these methods:

  • wait()

Wait () causes the current thread to change from executing to waiting until another thread executes notify() or notifyAll() on the current object.

  • wait(long timeout)

The difference with wait() is that if the notify() or notifyAll() has not been performed by the previous object after the timeout, the thread automatically starts execution.

Note that executing wait(0) has the same effect as waiting ().

  • wait(long timeout, int nanos)

Compared to wait(long timeout), this method provides a higher precision for waiting timeout Settings, down to nanoseconds.

1 millisecond = 1,000,000 nanoseconds.

  • notify()

For all threads waiting on the monitor for this object, performing notify() wakes up a random thread.

  • notifyAll()

In contrast to notify(), this method wakes up all the monitor threads waiting for the object.

The sample

Based on the above sample code, add the following code implementation.

Waiter:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Waiter implements Runnable{

    private Message msg;

    public Waiter(Message m){
        this.msg=m;
    }

    @Override
    public void run(a) {
        String name = Thread.currentThread().getName();
        synchronized (msg) {
            try{
                System.out.println(name+" : waiting to get notified at time:"+ LocalDateTime.now().format(DateTimeFormatter.ISO_TIME));
                msg.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(name+" : waiter thread got notified at time:"+LocalDateTime.now().format(DateTimeFormatter.ISO_TIME));
            //process the message now
            System.out.println(name+" : processed: "+msg.getMsg()); }}}Copy the code

Notifier:

public class Notifier implements Runnable {

    private boolean isAll = true;

    private Message msg;

    public Notifier(Message msg, boolean isAll) {
        this.msg = msg;
        this.isAll = isAll;
    }

    @Override
    public void run(a) {
        String name = Thread.currentThread().getName();
        System.out.println(name + " started");
        try {

            Thread.sleep(3000);

            synchronized (msg) {

                System.out.println(name + " : got the msg : "+msg.getMsg());

                msg.setMsg(name + " : Notifier work done");

                if (isAll) {
                    msg.notifyAll();
                } else{ msg.notify(); }}}catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code

WaitNotifyTest:

import java.util.concurrent.atomic.AtomicBoolean;

public class WaitNotifyTest {

    public static void main(String[] args) {
        //testPolling();
        testNotify();
        //testNotifyAll();
    }

    public static void testPolling(a) {

        Message msg = new Message("process it");

        PollingWaiter waiter = new PollingWaiter(msg);

        new Thread(waiter, "PollingWaiter").start();

        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        msg.setIsAvailable(new AtomicBoolean(true));
        System.out.println("over");
    }

    public static void testNotify(a) {
        Message msg = new Message("process it");

        Waiter waiter1 = new Waiter(msg);
        new Thread(waiter1, "waiter1").start();

        Waiter waiter2 = new Waiter(msg);
        new Thread(waiter2, "waiter2").start();

        Notifier notifier = new Notifier(msg, false);
        new Thread(notifier, "notifier").start();

        System.out.println("All the threads are started");
    }

    public static void testNotifyAll(a) {
        Message msg = new Message("process it");

        Waiter waiter1 = new Waiter(msg);
        new Thread(waiter1, "waiter1").start();

        Waiter waiter2 = new Waiter(msg);
        new Thread(waiter2, "waiter2").start();

        Notifier notifier = new Notifier(msg, false);
        new Thread(notifier, "notifier").start();

        System.out.println("All the threads are started"); }}Copy the code

If two threads execute wait at the same time, only one thread wakes up after notify, and the other thread is stuck waiting indefinitely.

Links

The warehouse address

  • Github.com/javastudyde…

  • See the complete sample code:

Github.com/javastudyde…

Refer to the link

  • www.geeksforgeeks.org/inter-threa…

  • www.baeldung.com/java-wait-n…

  • www.journaldev.com/1037/java-t…