Пробовал вложенные замки, но все еще в тупике - PullRequest
3 голосов
/ 08 февраля 2012

это код, в котором я пытаюсь продемонстрировать проблему вложенных блокировок,

  import java.util.concurrent.locks.*;


  class SharedResource{
    private static final Lock lock = new ReentrantLock();


    private void methodThree(String name,int x) throws Exception{
        lock.lock();
        while(x <= 15){
            System.out.println("METHOD-THREE / THREAD-NAME : "+name+" NUM-VAL "+x);
            x++;
            Thread.sleep(250);
        }
    }

    private void methodTwo(String name,int x) throws Exception{
        lock.lock();
        while(x <= 10){
            System.out.println("METHOD-TWO / THREAD-NAME : "+name+" NUM-VAL "+x);
            x++;
            Thread.sleep(250);
        }
        methodThree(name,x);
    }

    public void methodOne(String name,int x) throws Exception{
        try{        
            lock.lock();
            while(x <= 5){
                System.out.println("METHOD-ONE / THREAD-NAME : "+name+" NUM-VAL "+x);
                x++;
                Thread.sleep(250);
            }   
            methodTwo(name,x);          
        }finally{
            lock.unlock();
        }       
    }

  }

  class MyRequestREQ extends Thread{

    private SharedResource res;
    private int num = 1;

    MyRequestREQ(SharedResource res,String name){
        super(name);
        this.res = res;
    }

    @Override
    public void run(){      
        try{
            res.methodOne(Thread.currentThread().getName(),num);
        }catch(Exception e){
            System.out.println(e);
        }
    }
  }

  public class LockCountPractise{
    public static void main(String [] args){
        SharedResource resource = new SharedResource();
        MyRequestREQ[] requests = new MyRequestREQ[]{
            new MyRequestREQ(resource,"JACK"),
            new MyRequestREQ(resource,"JILL"),
            new MyRequestREQ(resource,"JASON")
        };

        for(int x=0; x < requests.length;x++){
            requests[x].start();
        }
    }
  }

, но вывод, который я получаю, выполняется одним потоком "JACK", этот поток печатает до счетчика 15и только что повесил трубку.

Есть ли у вышеуказанной программы проблема тупика?

нужно ли мне разблокировать блокировку во всех методах класса SharedResource?

Ожиданиеза предложение.

Ответы [ 2 ]

3 голосов
/ 08 февраля 2012

вы не разблокируете в method3, поэтому, когда первый поток завершен, другие не могут продолжить, поскольку они не могут получить блокировку.

мне нужно разблокировать блокировку во всех методах класса SharedResource?

да, потому что каждый раз, когда вы звоните lock():

Если текущий поток уже удерживает блокировку, тогда счетчик удержания увеличивается на единицу, и метод немедленно возвращается.

см: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html#lock%28%29

в качестве предложения: вы можете получить блокировку в method1 и снять ее в method3. так что будет 1 замок 1 разблокировать, все будет хорошо. нет необходимости 3 блокировки-разблокировки цикла.

на самом деле это зависит от того, какое поведение вы хотите:

  • Чтобы позволить различным потокам захватить блокировку между счетчиками (поток 1 считает до 5, затем поток 3 приходит и считает, затем поток 1 продолжается) вам необходимо разблокировать блокировку в каждом методе.
  • Чтобы начать и закончить один поток без какого-либо вмешательства, вам потребуется 1 блокировка-разблокировка
0 голосов
/ 08 февраля 2012

Джек блокирует замок три раза, но открывает только один раз.lock() считает:

lock ()

Если текущий поток уже удерживает блокировку, то счетчик удержаний увеличивается на единицу, и метод возвращаетнемедленно.

unlock ()

Если текущая нить является держателем этой блокировки, то количество удержаний уменьшается.Если счетчик удержания теперь равен нулю, блокировка снимается.

(JavaDoc)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...