2013-05-02 4 views
1

Я не знаком с потоками и параллельным программированием. Я искал простой фрагмент кода, который приведет в тупик, вот оно:Пример синхронизации Java с тупиком

public class TestLock { 
    private static class fun { 
     int a,b; 

     void read() {System.out.println(a+b);} 
     void write(int a,int b) {this.a=a;this.b=b;} 
    } 

    public static void main (String[] args) throws java.lang.Exception { 
     final fun d1=new fun(); 
     final fun d2=new fun(); 

     Thread t1=new Thread() { 
      public void run() { 
       for(int i=0;i<5;i++) { 
        synchronized(d2) { 
         d2.read(); 
         try { 
          Thread.sleep(50); 
         } catch (Exception ex) { 
          ex.printStackTrace(); 
         } 
         synchronized(d1) { 
          d1.write(i, i); 
        } 
       } 
      } 
     }; 

     Thread t2=new Thread() { 
      public void run() { 
       for(int i=0;i<5;i++) { 
        synchronized(d1) { 
         d1.read(); 
         try { 
          Thread.sleep(50); 
         } catch (Exception ex) { 
          ex.printStackTrace(); 
         } 
         synchronized(d2) { 
          d2.write(i, i); 
         } 
        } 
       } 
      } 
     }; 
     t1.start(); 
     t2.start(); 
    } 
} 

Теперь мне было интересно, как я мог бы превратить этот пример, используя ReentrantLock вместо синхронизируется, но я не вижу, как: для удовольствия нужно иметь атрибут ReentrantLock, чтобы иметь что-то вроде

Thread t1=new Thread() { 
    public void run() { 
     for(int i=0;i<5;i++) { 
      if(d2.lock.tryLock()) { 
        try {d1.read();Thread.sleep(50);} catch(Exception e) {e.printStackTrace();} finally {d1.lock.unlock();} 
         if(d2.lock.tryLock()) { 
          try {d2.write(i, i);} catch(Exception e) {e.printStackTrace();} finally {d2.lock.unlock();} 
         } 
        } 
       } 
      } 
     }; 

или я чего-то не хватает?

ответ

1

Преобразование примера с использованием ReentrantLocks действительно означало бы использование двух замков: один связанный с d1, а другой связанный с d2.

И вы бы заменить каждый вход в синхронизированный блок на dX вызовом lockX.lock(), и любой выход из синхронизированного блока на dX вызовом lockX.unlock() `.

Использование tryLock() поражает цель, так как она возвращает вместо ожидания, если блокировка не может быть получена.

Смежные вопросы