Java Topics: Using Sleep and Interrupts, rather than Waiting and Notifying

The script . Trying to achieve a result using sleep()and interrupt(); which would otherwise be fulfilled wait()andnotifyAll()

Question - I know that this method is not preferred. Can you guys tell me what is wrong by doing this in this below script.

One reason: notifyAll()notify all threads that are looking for a lock for this object. But with interrupt() we have a call interruption for each waiting thread explicitly.

Another reason is that another thread cannot change the state of the object. Here is the starting thread itself food=truewhen fishing InterruptedException. But what is wrong with that?

/**
 * Objective of this program:
 * 
 * I was thinking, why can't we achieve the guarded block with Sleep and Interrupt,
 * why only with wait and notify..
 * 
 * Wait releases lock; while Sleep does not . But both suspend the execution. 
 * So if you are synchronizing on the object, then we cannot have the second thread
 * to modify the object state due the lock on the object, and the second thread cannot acquire it.
 * 
 * So I did a explicit interrupt on the first thread.
 * 
 */
/**
 * 
 * One person ask if he has something to eat polling the "food" variable.
 * Another person updates the shared variable food.
 * 
 * food = true means the first person can start eating. food = false means he
 * has to wait and poll the value until food is available(food = true). This is
 * not a producer-consumer problem.
 * 
 */

public class _17GuardedBlockWithSleep_Interrupt_Badcase {

    static class Person {

        volatile boolean food;

        public boolean isFood() {
            return food;
        }

        public void setFood(boolean food) {
            this.food = food;
        }

        String name;

        Person(String name) {
            this.name = name;
        }

        /*
         * Sloppy/Bad way of implementation making it pause execution until it
         * gets interrupted. An interruption alone does not mean food is
         * available. May be interrupt was called by someone else who does not
         * provide food. So check the condition too.
         * 
         * Through sleep(), the execution is paused. CPU is free to take other
         * tasks, The lock on object is NOT released so other threads CANNOT
         * acquire the lock on the object.
         */

        // Guarded Block
        public synchronized void eatFood() {
            while (!isFood()) {
                // food is currently unavailable. I'm waiting..
                try {
                    /**
                     * Ideally we do wait() and notifyAll() in such a scenario. I am
                     * trying with Sleep and Interrupt.
                     */
                    Thread.sleep(1000000000);
                } catch (InterruptedException e) {
                    this.setFood(true);// it not some other thread that provide food. it itself!
                    System.out.println("eatFood() caught InterruptedException");
                    // e.printStackTrace();
                }
            }
            // if control comes here, then it means food is available
            System.out.println("got the food.. yummyy..thanks!");
        }

        public synchronized void provideFood(Thread t) {
            this.setFood(true); // this refers to current object. In this case, the
                                        // 'kuttappan' object
            // interrupt the first thread
            t.interrupt();
        }

    }

    public static void main(String[] args) {
        final Person kuttappan = new Person("Kuttappan");

        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                /*
                 * if kuttappan is not already defined as final, you get an error
                 * "Cannot refer to a non-final variable kuttappan inside an inner class defined in a different method"
                 */
                kuttappan.eatFood();
                /*
                 * thread will try to acquire the lock on 'kuttappan' object when it
                 * invokes the synchronized method.
                 */
            }
        };
        final Thread t = new Thread(runnable1, "thread1");
        t.start();

        // someone is needed to make the food available for kuttappan.

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000); // 5 seconds
                    t.interrupt(); // MY IMPORTANT LINE
                    // kuttappan.provideFood(t);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

/**
 * OUTPUT:
 * 
 * Observe the line commented as "MY IMPORTANT LINE"
 * 
 * If you do 'kuttappan.provideFood(t);' then the program Keeps on running. no
 * output, because
 * 
 * The second thread cannot get into provideFood() of kuttappan object because
 * the first thread has not released the lock on the object!
 * 
 * But if you do t.interrupt(); the thread is interrupted and the program
 * behaves as expected.
 */
+4
3

: wait() sleep()

" a Thread , , , wait()."

, , , , , .

, t.interrupt(), , , . , ... ...

, . , , , , . , , , , , ...

+2

, , . IPC. , , .

+1

, , interrupt() "".

If you use wait()/ notify(), you do not need threads to know each other, you only need a synchronization point - the object you are waiting for / notify. You can also share this object with as many threads as you want. Therefore, at the end of the downward flow of manufacturers, they do not care who exactly is waiting for the resource, they only need to send a signal that the resource is available.

+1
source

Source: https://habr.com/ru/post/1539062/


All Articles