ReentrantLock не дает ожидаемого результата

Я создал программу-производитель, использующую функцию потоков (ожидание и уведомление). Код -

/**
 *  Message.java ( Common object )
 */
package threads;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author chouhan_r
 *
 */
public class Message {
    private String message;

    ReentrantLock lock = new ReentrantLock();
    ReentrantLock takelock = new ReentrantLock();
    private boolean empty =true;
    public  void put(String message){
        lock.lock();
        while(!empty){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        empty = false;
        this.message = message;

        notifyAll();
        lock.unlock();
    }

    public String take(){

        takelock.lock();
        while(empty){
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        empty = true;

        notifyAll();
        takelock.unlock();
        return message;

    }


}


/**
 * Producer.java
 */
package threads;

import java.util.Random;

public class Producer implements Runnable{
    private Message message;
    public Producer(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        String[] impInfo = {"Hello", "I am here", "why are you doing this ??", "No problem" };
        Random random = new Random();
        for(String str : impInfo){
            message.put(str);
            try {
                Thread.sleep(random.nextInt(3000));
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        message.put("Finished");

    }



}

/**
 * Consumer.java
 */
package threads;

public class Consumer implements Runnable{
    private Message message;
    public Consumer(Message message) {
        this.message = message;
    }
    @Override
    public void run() {
        System.out.println(message);
        String msg = message.take();
        while(!"Finished".equalsIgnoreCase(msg)){
            System.out.println(msg);
            msg = message.take();
        }


    }


}

=====================

/**
 * Main Program
 */
package threads;

public class ProConsTest {

    public static void main(String[] args) {
        Message message = new Message();
        new Thread(new Consumer(message)).start();
        new Thread(new Producer(message)).start();



    }

}

Я пытаюсь выполнить этот код с помощью ReentrantLock, но он дает мне ошибку:

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at threads.Message.take(Message.java:39)
    at threads.Consumer.run(Consumer.java:11)
    at java.lang.Thread.run(Unknown Source)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)
    at threads.Message.put(Message.java:31)
    at threads.Producer.run(Producer.java:16)
    at java.lang.Thread.run(Unknown Source)

Я что-то здесь не так делаю ?? когда я отмечаю методы в Message.java как синхронизированные, они прекрасно работают. Можем ли мы запустить этот код только с замком Reentrant ??

Ответы на вопрос(1)

Ваш ответ на вопрос