DeadLock в производителе-потребителе

    I have following classes :

    package com.akshu.multithreading;

    public class ThreadResource {

        static int a;
     static boolean Value =false;
        public synchronized int getA() {
            while(Value == false){
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            Value= false;
            notify();


            return a;
        }

        public synchronized void setA(int a) {
            while(Value == true)
            {
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            ThreadResource.a = a;
            Value=true;
            notify();

        }


    }


    ------------------


    /**
     * 
     */
    package com.akshu.multithreading;

    /**
     * @author akshu
     *
     */
    public class MyThreadA implements Runnable  {

        int a = 0;
        ThreadResource tR= new ThreadResource();

        @Override
        public void run() {


        for (int i = 0; i < 15; i++) {



            tR.setA(++a);
            System.out.println(" value of a :"+a);





        }

        }
    }

    ------------

    package com.akshu.multithreading;

    public class MyThreadB implements Runnable {

        @Override
    public void run() {
        // TODO Auto-generated method stub
        ThreadResource tR =new ThreadResource();
        for (int i = 0; i < 15; i++) {

        System.out.println("getA()"+tR.getA());

                }
    }
    }
    ----

    package com.akshu.multithreading;

    public class ThreadExecutionPoint {

        public static void main(String args[])  {

            Thread th1 = new Thread(new MyThreadA());
            Thread th2 = new Thread(new MyThreadB());

            th1.start();
            th2.start();
        }
    }

Я пытаюсь понять проблему производителя-потребителя с помощью приведенного выше кода. Когда я выполняю приведенный выше код, я получаю

    value of a :1
    getA()1

Программа зависает только здесь (не завершается).

Кто-нибудь, пожалуйста, объясните, что я здесь делаю неправильно?


person noone    schedule 17.03.2013    source источник
comment
Могу ли я сказать, что это не лучший способ понять проблему производителя/потребителя.   -  person Kakalokia    schedule 17.03.2013
comment
@AliAlamiri: Хорошо. Что не так с этим примером. Не могли бы вы предложить что-то еще.   -  person noone    schedule 17.03.2013
comment
это может помочь java.dzone.com/articles/concurrency-pattern-producer   -  person Kakalokia    schedule 17.03.2013


Ответы (1)


Объявить Value как volatile
Т.е. static volatile boolean Value =false;
Вы объявили свои set/get методы synchronized. Это означает, что они заблокированы на this (внутренняя блокировка объекта).
Но в вашем коде вы создаете отдельный экземпляр ThreadResource для каждого потока, тем самым не делая их synchronized, поскольку this для каждого случая разный.
Измените код следующим образом:

public class MyThreadA implements Runnable {  
    ThreadResource tR;  

     public MyThreadA(ThreadResource tr) {  
        this.tR = tr;  
    }  
// your run method here NOT declaring a ThreadResource anymore!!!
}   

и то же самое для MyThreadB

Затем в ThreadExecutionPoint

ThreadResource tr = new ThreadResource();  
Thread th1 = new Thread(new MyThreadA(tr));  
Thread th2 = new Thread(new MyThreadB(tr));  
person Cratylus    schedule 17.03.2013
comment
Понял, спасибо!! :) . Я создавал два объекта и создавал два потока по одному для каждого. Таким образом, в основном вся цель многопоточности была потеряна. Метод wait() ожидал объекта, который не использовался ни одним другим потоком. - person noone; 18.03.2013
comment
@AkshuJain: вы не были synchronized на одной и той же блокировке. Это была ваша основная проблема. synchronized - это блокировка this, и в вашем случае вы использовали другой this, т.е. объект для блокировки - person Cratylus; 18.03.2013